欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

详谈Java几种线程池类型介绍及使用方法

程序员文章站 2024-03-04 14:09:59
一、线程池使用场景 •单个任务处理时间短 •将需处理的任务数量大 二、使用java线程池好处 1、使用new thread()创建线程的弊端...

一、线程池使用场景

•单个任务处理时间短

•将需处理的任务数量大

二、使用java线程池好处

1、使用new thread()创建线程的弊端:

•每次通过new thread()创建对象性能不佳。

•线程缺乏统一管理,可能无限制新建线程,相互之间竞争,及可能占用过多系统资源导致死机或oom。

•缺乏更多功能,如定时执行、定期执行、线程中断。

2、使用java线程池的好处:

•重用存在的线程,减少对象创建、消亡的开销,提升性能。

•可有效控制最大并发线程数,提高系统资源的使用率,同时避免过多资源竞争,避免堵塞。

•提供定时执行、定期执行、单线程、并发数控制等功能。

java四种线程池

java里面线程池的*接口是executor,但是严格意义上讲executor并不是一个线程池,而只是一个执行线程的工具。真正的线程池接口是executorservice。下面这张图完整描述了线程池的类体系结构:

详谈Java几种线程池类型介绍及使用方法

1. newcachedthreadpool

创建一个可根据需要创建新线程的线程池,但是在以前构造的线程可用时将重用它们。对于执行很多短期异步任务的程序而言,这些线程池通常可提高程序性能。调用 execute 将重用以前构造的线程(如果线程可用)。如果现有线程没有可用的,则创建一个新线程并添加到池中。终止并从缓存中移除那些已有 60 秒钟未被使用的线程。因此,长时间保持空闲的线程池不会使用任何资源。

public static executorservice newcachedthreadpool()

示例代码:

public class threadpoolexecutortest {
   public static void main(string[] args ) {
    executorservice cachethreadpool =executors.newcachedthreadpool();
     for(int i =1;i<=5;i++){
       final int index=i ;
       try{
        thread.sleep(1000);
      }catch(interruptedexception e ) {
         e.printstacktrace();
      }
       cachethreadpool.execute(new runnable(){
         @override
         public void run() {
          system.out.println("第" +index +"个线程" +thread.currentthread().getname());  
        }  
      });
    }
  }
}


//输出结果
第1个线程pool-1-thread-1
第2个线程pool-1-thread-1
第3个线程pool-1-thread-1
第4个线程pool-1-thread-1 第5个线程pool-1-thread-1  

由结果可看出 当执行第二个任务时第一个任务已经完成,会复用执行第一个任务的线程,而不用每次新建线程。

2. newfixedthreadpool

创建一个指定工作线程数量的线程池。每当提交一个任务就创建一个工作线程,如果工作线程数量达到线程池初始的最大数,则将提交的任务存入到池队列中。

public static executorservice newfixedthreadpool(int nthreads)

nthreads - 池中的线程数

示例代码:

public class threadpoolexecutortest {
   public static void main(string[] args) {
    executorservice fixedthreadpool =executors. newfixedthreadpool(3);
     for (int i =1; i<=5;i++){
       final int index=i ;
       fixedthreadpool.execute(new runnable(){
         @override
         public void run() {
           try {
            system.out.println("第" +index + "个线程" +thread.currentthread().getname());
            thread.sleep(1000);
          } catch(interruptedexception e ) {
             e .printstacktrace();
          }
        }

      });
    }
  }
}

由于设置最大线程数为3,所以在输出三个数后等待2秒后才继续输出。

2. newscheduledthreadpool

创建一个线程池,它可安排在给定延迟后运行命令或者定期地执行。

public static scheduledexecutorservice newscheduledthreadpool(int corepoolsize)

corepoolsize - 池中所保存的线程数,即使线程是空闲的也包括在内。

延迟执行示例代码:

public class threadpoolexecutortest {  
  public static void main(string[] args) {
    scheduledexecutorservice scheduledthreadpool= executors.newscheduledthreadpool(3);   
    scheduledthreadpool.schedule(newrunnable(){     
      @override 
      public void run() {
       system.out.println("延迟三秒");
       }
   }, 3, timeunit.seconds);
  }
}

表示延迟3秒执行。

定期执行示例代码:

public class threadpoolexecutortest {  
  public static void main(string[] args) {

    scheduledexecutorservice scheduledthreadpool= executors.newscheduledthreadpool(3);    
  scheduledthreadpool.scheduleatfixedrate(newrunnable(){    
    @override      
    public void run() {
       system.out.println("延迟1秒后每三秒执行一次");
     }
   },1,3,timeunit.seconds);
 }

}

表示延迟1秒后每3秒执行一次。

4.newsinglethreadexecutor

创建一个使用单个 worker 线程的 executor,以*队列方式来运行该线程。(注意,如果因为在关闭前的执行期间出现失败而终止了此单个线程,那么如果需要,一个新线程将代替它执行后续的任务)。可保证顺序地执行各个任务,并且在任意给定的时间不会有多个线程是活动的。与其他等效的 newfixedthreadpool(1)不同,可保证无需重新配置此方法所返回的执行程序即可使用其他的线程。

public static executorservice newsinglethreadexecutor()

示例代码:

public class threadpoolexecutortest {  
  public static void main(string[] args) {
    executorservice singlethreadpool= executors.newsinglethreadexecutor();    
    for(int i=1;i<=5;i++){      
      int index=i;      
    singlethreadpool.execute(new runnable(){
       @override
       public void run() {         
        try{
         system.out.println("第"+index+"个线程");
        thread.sleep(2000);
         }catch(interruptedexception e) {            
          e.printstacktrace();
        }
      } });
    }
  }
}

以上这篇详谈java几种线程池类型介绍及使用方法就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持。