线程池有几种(Java并发类库提供的线程池有哪几种? 分别有什么特点?)

线程不能重复启动,创建或销毁线程存在一定的开销,所以利用线程池技术来提高系统资源利用效率,并简化线程管理。

Executor 框架

Java提供的线程池框架主要涉及到如下的类和接口:

  • executors: 通过很多静态方法,提供不同的预配置的线程池;
  • Executor: Executor 是最上层的接口,只包含execute(Runnable command)方法;
  • ExecutorService: Executor的子接口;包含很多有用的方法,例如submit()、shutdown()、shutdownNow()、awaitTermination()、invokeAll();
  • ThreadPoolExecutor: 具体的线程池的实现类;

Executor 框架基本组成

下面是相应的代码:

public interface Executor {

void execute(Runnable command);

}

public interface ExecutorService extends Executor {... ...}

public class ThreadPoolExecutor extends AbstractExecutorService {... ...}

工具类 Executors

主要提供以下几种预配置的线程池:

1. newFixedThreadPool(int nThreads) 创建一个包含nThreads个线程的线程池,共享一个无边界的工作队列,在任何时刻,线程池最多有nThreads个存活线程;当某个线程由于执行过程中出现错误而死亡,则新建一个线程以补充。

线程池

Executor exe = Executors.newFixedThreadPool(5);

exe.execute(new Runnable() {

@Override

public void run() {

// TODO Auto-generated method stub

}

});

2. newCachedThreadPool() 创建一个线程池,当新任务被提交,如果池中没有空余的存活线程,则该线程池会创建新的线程;如果有存活的多余的线程则会复用该线程;当某个线程空闲超过60秒的时候,该线程会被终止然后被移除线程池。

这种线程池适合被用于处理大量耗时短的任务,因为设置了一个空闲超时时间,这样当整个线程池都闲下来时,基本不会占用额外的资源。其内部使用 SynchronousQueue 作为工作队列。

Executor exe = Executors.newCachedThreadPool();

exe.execute(new Runnable() {

@Override

public void run() {

// TODO Auto-generated method stub

});

3. newSingleThreadExecutor() 创建仅仅包含一个线程的线程池,维护着一个无边界的工作队列,在任何时刻,线程池只能有一个任务被执行,任务被保证顺序的执行。如果线程由于执行过程中出现错误而死亡,则新建一个线程代替继续执行任务;和newFixedThreadPool(1)不一样,一旦线程池创建,该线程池不能再进行配置。这是通过将ThreadPoolExecutor 包装类实现的,因此该方法返回的Executor不能强制转化为ThreadPoolExecutor;

4. newSingleThreadScheduledExecutor() 和 newScheduledThreadPool(int coreThreadSize) 分别是创建包含一个线程和指定数量的线程,该线程池的线程定时的执行一些任务;

5. newWorkStealingPool(int parallelism),newWorkStealingPool是jdk1.8才有的,会根据所需的并行层次来动态创建和关闭线程,通过使用多个队列减少竞争,底层用的ForkJoinPool来实现的。

ForkJoinPool的优势在于,可以充分利用多cpu、多核cpu的优势,把一个任务拆分成多个“小任务”,把多个“小任务”放到多个处理器核心上并行执行;当多个“小任务”执行完成之后,再将这些执行结果合并起来即可。

有两个方法用于创建ForkJoin框架中用到的ForkJoinPool线程池,第一个函数中的参数用于指定并行数,第二个函数没有参数,它默认使用当前机器可用的CPU个数作为并行数。

您可以还会对下面的文章感兴趣

最新评论

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

使用微信扫描二维码后

点击右上角发送给好友