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

JDK中的线程池(ThreadPoolExecutor) jdkthreadpool 

程序员文章站 2022-07-12 19:50:42
...
1.ThreadPoolExecutor =>
线程池在启动后,不管有没有任务来时,就会先创建coreSize个线程数。

(1)、使用有界队列(ArrayBlockingQueue):=>maxPoolSize和队列大小需要平衡。
当要执行的任务数小于coreSize时,就用coreSize个线程执行任务,
当任务数等于coreSize的大小时,新来一个任务,则首先将任务放入队列中,以此类推,直到队列满;
当队列满时,再新来一个任务,则新开一个线程,以此类推,直到达到线程池的最大值。
当队列满并且最大线程数到达时,再新来一个任务,执行拒绝策略。
/////////begin//////
private final ThreadPoolExecutor executor = new ThreadPoolExecutor(10, 25, 1000, TimeUnit.MILLISECONDS,
   new ArrayBlockingQueue<Runnable>(70),new ThreadPoolExecutor.CallerRunsPolicy());
////////end/////////
(2)、使用*队列(LinkedBlockingQueue):=>maxPoolSize失效
当要执行的任务数小于coreSize时,就用coreSize个线程执行任务,
当任务数等于coreSize的大小时,新来一个任务,则新开一个线程,以此类推,直到队列满(如果队列的size无限大,则不会满)。
/////////begin///////
private final ThreadPoolExecutor executor = new ThreadPoolExecutor(10, 25, 1000, TimeUnit.MILLISECONDS,
   new LinkedBlockingQueue<Runnable>(Integer.MAX_VALUE),new ThreadPoolExecutor.CallerRunsPolicy());
/////////end/////////
(3)、使用直接提交(SynchronousQueue):=>
当有任务来时,总是开启新线程来执行任务。因此,建议maxPoolSize要足够大,否则会丢弃任务。
////////begin////////
private final ThreadPoolExecutor executor = new ThreadPoolExecutor(10, 20, 1000, TimeUnit.MILLISECONDS,
   new SynchronousQueue<Runnable>(),new ThreadPoolExecutor.CallerRunsPolicy());
//////////end////////

结论:使用有界队列和CallerRunsPolicy 保证线程池的可伸缩性。比如:
////////begin///////
private static  ThreadPoolExecutor executor = new ThreadPoolExecutor(5, 30, 1000, TimeUnit.MILLISECONDS,
   new ArrayBlockingQueue<Runnable>(10),new ThreadPoolExecutor.CallerRunsPolicy());
///////////end//////
注意:【jdk线程池的bug】目前jdk6及之前的版本有bug,需要使用jdk7之后的版本。参见:
【http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6458662】

注意:CallerRunsPolicy策略
==>A handler for rejected tasks that runs the rejected task directly in the calling thread of the execute method

关于【CallerRunsPolicy】,如果线程main中调用了线程池方法,如:executor.submit()或者executor.execute(),那么当线程池以最大线程在运行并且排队队列也变满时,
此时再进来一个任务的情况下,该任务就执行CallerRunsPolicy策略的语义(字面义也是调用者运行的意思),即让调用线程池的调用者来运行该任务,当此任务执行时间比较长时,会出现
线程池中的线程已空闲,但是调用者线程还没有执行完长任务时,再来新任务就不会被加入线程池中,直到调用者线程执行完毕。
相关标签: jdk threadpool