java ExecutorService 线程池

最近在做项目时,需要用到线程池。

我不喜欢一开始上来就讲底层,因为这样子很深奥。

对于线程池,java jdk 1.7里会有对应的接口ExecutorService与实现类newCachedThreadPool /newFixedThreadPool /newScheduledThreadPool 。

这篇博客里推荐新手先看看,因为如果只关注怎么用,先不扔源码的话,是够用的。《java ExecutorService

newCachedThreadPool :可缓存,也就是他会利用已经运行完毕的线程,比如线程池里有A、B两个线程,如果现在又来一个请求C。如果线程A现在是空闲的,则可以用线程A来接受请求C,而不用再去new一个线程。

 newFixedThreadPool :定长的线程池。也就是池里的最大线程数是固定的。

  • 如果你的线程池容量为10,线程池里有A、B两个线程。如果现在又来一个请求C,他是不会检查之前的线程进行复用。而是会创建一个新的线程C来接收请求C。
  • 如果当前线程池里已经有10个线程,这时候又来一个新的请求。此时才会去检查池里是否有空闲的线程,如果有的话就利用旧的空闲线程去接收请求。如果没有的话就放在等待队列里。而且直到线程池shutDown(),否则线程池里的线程是没有办法在内存里释放的
  • 需要注意的是,newFixedThreadPool的源码里的等待队列使用的是 LinkedBlockingQueue<Runnable>()。当等待队列是LinkedBlockingQueue的时候,所以该线程池的第二个初始化参数public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime, TimeUnit unit,BlockingQueue<Runnable> workQueue)是无效的。所以如果直接ExecutorService fixedThreadPool = Executors.newFixedThreadPool(3)这样子建议线程池,则只是确认了第一个参数corePoolSize。第二个参数maximumPoolSize虽然被设置,但是没有实际效果。如果超过corePoolSize,会全部加到阻塞队列里面去。

newScheduledThreadPool :用于定时任务或周期性任务执行。


如果你不想使用上面那些,可以自定义线程池,如下:

 
 
ThreadPoolExecutor pool = new ThreadPoolExecutor(1, 2, 2, TimeUnit.HOURS, new LinkedBlockingQueue<Runnable>());

参数的含义分别为:【引用:Java多线程-线程池ThreadPoolExecutor构造方法和规则

  • corePoolSize

    核心线程数,默认情况下核心线程会一直存活,即使处于闲置状态也不会受存keepAliveTime限制。除非将allowCoreThreadTimeOut设置为true

  • maximumPoolSize

    线程池所能容纳的最大线程数。超过这个数的线程将被阻塞。当任务队列为没有设置大小的LinkedBlockingDeque时,这个值无效。

  • keepAliveTime

    非核心线程的闲置超时时间,超过这个时间就会被回收。

  • unit

    指定keepAliveTime的单位,如TimeUnit.SECONDS。当将allowCoreThreadTimeOut设置为true时对corePoolSize生效。

  • workQueue

    线程池中的任务队列.

    常用的有三种队列,SynchronousQueue,LinkedBlockingDeque,ArrayBlockingQueue



猜你喜欢

转载自blog.csdn.net/weixin_41048746/article/details/80366008