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个数作为并行数。

    声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!

    上一篇 2019年3月12日
    下一篇 2019年3月12日

    相关推荐