Java多线程--线程池

原文链接: http://www.imrookie.cn/article/java-thread-pool

ThreadPoolExecutor

使用方法:调用线程池的execute(Runnable command)方法;

任务交给线程池后的处理策略:

1.如果当前线程池中的线程数目小于corePoolSize,则每来一个任务,就会创建一个线程去执行这个任务;
2.如果当前线程池中的线程数目>=corePoolSize,则每来一个任务,会尝试将其添加到任务缓存队列当中,若添加成功,则该任务会等待空闲线程将其取出去执行;若添加失败(一般来说是任务缓存队列已满),则会尝试创建新的线程去执行这个任务;
3.如果当前线程池中的线程数目达到maximumPoolSize,则会采取任务拒绝策略进行处理;
4.如果线程池中的线程数量大于 corePoolSize时,如果某线程空闲时间超过keepAliveTime,线程将被终止,直至线程池中的线程数目不大于corePoolSize;如果允许为核心池中的线程设置存活时间,那么核心池中的线程空闲时间超过keepAliveTime,线程也会被终止。

ThreadPoolExecutor有个内部类Worker

worker的核心功能为执行任务,执行完成后循环向任务缓存队列取任务来执行.

ThreadPoolExecutor提供了任务执行前后的监听方法

  1. protectedvoid beforeExecute(Thread t,Runnable r){}
  2. protectedvoid afterExecute(Runnable r,Throwable t){}
可以通过继承ThreadPoolExecutor类重写这2个方法来监控任务的执行.
在中断worker时使用锁.tryLock()来判断当前worker是否空闲.

线程池常用方法:

prestartCoreThread() 初始化1个核心线程
prestartAllCoreThreads() 初始化所有的核心线程
   

任务拒绝策略:

当线程池的任务缓存队列已满并且线程池中的线程数目达到maximumPoolSize,如果还有任务到来就会采取任务拒绝策略,通常有以下四种策略:
ThreadPoolExecutor.AbortPolicy:丢弃任务并抛出RejectedExecutionException异常。
ThreadPoolExecutor.DiscardPolicy:也是丢弃任务,但是不抛出异常。
ThreadPoolExecutor.DiscardOldestPolicy:丢弃队列最前面的任务,然后重新尝试执行任务(重复此过程)
ThreadPoolExecutor.CallerRunsPolicy:由调用线程处理该任务

线程池的关闭:

ThreadPoolExecutor提供了两个方法,用于线程池的关闭,分别是shutdown()和shutdownNow(),其中:

  • shutdown():不会立即终止线程池,而是要等所有任务缓存队列中的任务都执行完后才终止,但再也不会接受新的任务
  • shutdownNow():立即终止线程池,并尝试打断正在执行的任务,并且清空任务缓存队列,返回尚未执行的任务

线程池动态改变大小:

ThreadPoolExecutor提供了动态调整线程池容量大小的方法:setCorePoolSize()和setMaximumPoolSize(),

  • setCorePoolSize:设置核心池大小
  • setMaximumPoolSize:设置线程池最大能创建的线程数目大小

当上述参数从小变大时,ThreadPoolExecutor进行线程池容量赋值,还可能立即创建新的线程来执行任务。

线程池的使用:

    java doc并不建议我们直接使用 ThreadPoolExecutor,而是使用Executors类中提供的几个静态方法创建线程池;
Executors.newCachedThreadPool();        //创建一个缓冲池,缓冲池容量大小为Integer.MAX_VALUE
阻塞队列使用的SynchronousQueue,任务进来就创建新线程去执行,空闲60秒就销毁线程.
Executors.newSingleThreadExecutor();   //创建容量为1的缓冲池,使用的LinkedBlockingQueue
Executors.newFixedThreadPool(int);    //创建固定容量大小的缓冲池,使用的LinkedBlockingQueue
除了这几种,还有其他创建线程池的方法.

个人理解

    线程池其实是使用它准备好的线程来执行我们提供的任务的run()方法,并不是以new Thread(任务)方式来跑的;它负责管理它创建的线程(其实就是new Thread(Worker worker)),在它创建的线程里通过调用任务.run()来完成我们的任务.

猜你喜欢

转载自www.cnblogs.com/wangjiyu/p/9163884.html