Java ThreadPoolExecutor的参数深入理解
java threadpoolexecutor的参数深入理解
一、使用executors创建线程池
之前创建线程的时候都是用的executors的newfixedthreadpool(),newsinglethreadexecutor(),newcachedthreadpool()这三个方法。当然executors也是用不同的参数去new threadpoolexecutor
1. newfixedthreadpool()
创建线程数固定大小的线程池。 由于使用了linkedblockingqueue所以maximumpoolsize 没用,当corepoolsize满了之后就加入到linkedblockingqueue队列中。每当某个线程执行完成之后就从linkedblockingqueue队列中取一个。所以这个是创建固定大小的线程池。
public static executorservice newfixedthreadpool(int nthreads) { return new threadpoolexecutor(nthreads, nthreads, 0l, timeunit.milliseconds, new linkedblockingqueue<runnable>()); } public threadpoolexecutor(int corepoolsize, int maximumpoolsize, long keepalivetime, timeunit unit, blockingqueue<runnable> workqueue) { this(corepoolsize, maximumpoolsize, keepalivetime, unit, workqueue, executors.defaultthreadfactory(), defaulthandler); }
2.newsinglethreadpool()
创建线程数为1的线程池,由于使用了linkedblockingqueue所以maximumpoolsize 没用,corepoolsize为1表示线程数大小为1,满了就放入队列中,执行完了就从队列取一个。
public static executorservice newsinglethreadexecutor() { return new finalizabledelegatedexecutorservice (new threadpoolexecutor(1, 1, 0l, timeunit.milliseconds, new linkedblockingqueue<runnable>())); }
3.newcachedthreadpool()
创建可缓冲的线程池。没有大小限制。由于corepoolsize为0所以任务会放入synchronousqueue队列中,synchronousqueue只能存放大小为1,所以会立刻新起线程,由于maxumumpoolsize为integer.max_value所以可以认为大小为2147483647。受内存大小限制。
public static executorservice newcachedthreadpool() { return new threadpoolexecutor(0, integer.max_value, 60l, timeunit.seconds, new synchronousqueue<runnable>()); } public threadpoolexecutor(int corepoolsize, int maximumpoolsize, long keepalivetime, timeunit unit, blockingqueue<runnable> workqueue) { this(corepoolsize, maximumpoolsize, keepalivetime, unit, workqueue, executors.defaultthreadfactory(), defaulthandler); }
二、使用threadpoolexecutor创建线程池
threadpoolexecutor的构造函数
public threadpoolexecutor(int corepoolsize, int maximumpoolsize, long keepalivetime, timeunit unit, blockingqueue<runnable> workqueue, threadfactory threadfactory, rejectedexecutionhandler handler) { if (corepoolsize < 0 || maximumpoolsize <= 0 || maximumpoolsize < corepoolsize || keepalivetime < 0) throw new illegalargumentexception(); if (workqueue == null || threadfactory == null || handler == null) throw new nullpointerexception(); this.corepoolsize = corepoolsize; this.maximumpoolsize = maximumpoolsize; this.workqueue = workqueue; this.keepalivetime = unit.tonanos(keepalivetime); this.threadfactory = threadfactory; this.handler = handler; }
参数:
1、corepoolsize核心线程数大小,当线程数<corepoolsize ,会创建线程执行runnable
2、maximumpoolsize 最大线程数, 当线程数 >= corepoolsize的时候,会把runnable放入workqueue中
3、keepalivetime 保持存活时间,当线程数大于corepoolsize的空闲线程能保持的最大时间。
4、unit 时间单位
5、workqueue 保存任务的阻塞队列
6、threadfactory 创建线程的工厂
7、handler 拒绝策略
任务执行顺序:
1、当线程数小于corepoolsize时,创建线程执行任务。
2、当线程数大于等于corepoolsize并且workqueue没有满时,放入workqueue中
3、线程数大于等于corepoolsize并且当workqueue满时,新任务新建线程运行,线程总数要小于maximumpoolsize
4、当线程总数等于maximumpoolsize并且workqueue满了的时候执行handler的rejectedexecution。也就是拒绝策略。
threadpoolexecutor默认有四个拒绝策略:
1、threadpoolexecutor.abortpolicy() 直接抛出异常rejectedexecutionexception
2、threadpoolexecutor.callerrunspolicy() 直接调用run方法并且阻塞执行
3、threadpoolexecutor.discardpolicy() 直接丢弃后来的任务
4、threadpoolexecutor.discardoldestpolicy() 丢弃在队列中队首的任务
当然可以自己继承rejectedexecutionhandler来写拒绝策略.
int corepoolsize = 1; int maximumpoolsize = 2; int keepalivetime = 10; // blockingqueue<runnable> workqueue = new linkedblockingqueue<runnable>(); blockingqueue<runnable> workqueue = new arrayblockingqueue<runnable>(5); threadfactory threadfactory = executors.defaultthreadfactory(); //线程池和队列满了之后的处理方式 //1.跑出异常 rejectedexecutionhandler handler = new threadpoolexecutor.abortpolicy(); rejectedexecutionhandler handler2 = new threadpoolexecutor.callerrunspolicy(); rejectedexecutionhandler handler3 = new threadpoolexecutor.discardpolicy(); rejectedexecutionhandler handler4 = new threadpoolexecutor.discardoldestpolicy(); threadpoolexecutor threadpoolexecutor = new threadpoolexecutor(corepoolsize, maximumpoolsize, keepalivetime, timeunit.seconds, workqueue, threadfactory, handler2); for (int j = 1; j < 15; j++) { threadpoolexecutor.execute(new runnable() { public void run() { try { system.out.println(thread.currentthread().getname()); timeunit.seconds.sleep(1); } catch (interruptedexception e) { e.printstacktrace(); } } }); } system.out.println(threadpoolexecutor); }
感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!
上一篇: Quartz配置