Java ThreadPoolExecutor的参数深入理解
JavaThreadPoolExecutor的参数深入理解
一、使用Executors创建线程池
之前创建线程的时候都是用的Executors的newFixedThreadPool(),newSingleThreadExecutor(),newCachedThreadPool()这三个方法。当然Executors也是用不同的参数去newThreadPoolExecutor
1.newFixedThreadPool()
创建线程数固定大小的线程池。由于使用了LinkedBlockingQueue所以maximumPoolSize没用,当corePoolSize满了之后就加入到LinkedBlockingQueue队列中。每当某个线程执行完成之后就从LinkedBlockingQueue队列中取一个。所以这个是创建固定大小的线程池。
publicstaticExecutorServicenewFixedThreadPool(intnThreads){ returnnewThreadPoolExecutor(nThreads,nThreads, 0L,TimeUnit.MILLISECONDS, newLinkedBlockingQueue()); } publicThreadPoolExecutor(intcorePoolSize, intmaximumPoolSize, longkeepAliveTime, TimeUnitunit, BlockingQueue workQueue){ this(corePoolSize,maximumPoolSize,keepAliveTime,unit,workQueue, Executors.defaultThreadFactory(),defaultHandler); }
2.newSingleThreadPool()
创建线程数为1的线程池,由于使用了LinkedBlockingQueue所以maximumPoolSize没用,corePoolSize为1表示线程数大小为1,满了就放入队列中,执行完了就从队列取一个。
publicstaticExecutorServicenewSingleThreadExecutor(){ returnnewFinalizableDelegatedExecutorService (newThreadPoolExecutor(1,1, 0L,TimeUnit.MILLISECONDS, newLinkedBlockingQueue())); }
3.newCachedThreadPool()
创建可缓冲的线程池。没有大小限制。由于corePoolSize为0所以任务会放入SynchronousQueue队列中,SynchronousQueue只能存放大小为1,所以会立刻新起线程,由于maxumumPoolSize为Integer.MAX_VALUE所以可以认为大小为2147483647。受内存大小限制。
publicstaticExecutorServicenewCachedThreadPool(){ returnnewThreadPoolExecutor(0,Integer.MAX_VALUE, 60L,TimeUnit.SECONDS, newSynchronousQueue()); } publicThreadPoolExecutor(intcorePoolSize, intmaximumPoolSize, longkeepAliveTime, TimeUnitunit, BlockingQueue workQueue){ this(corePoolSize,maximumPoolSize,keepAliveTime,unit,workQueue, Executors.defaultThreadFactory(),defaultHandler); }
二、使用ThreadPoolExecutor创建线程池
ThreadPoolExecutor的构造函数
publicThreadPoolExecutor(intcorePoolSize, intmaximumPoolSize, longkeepAliveTime, TimeUnitunit, BlockingQueueworkQueue, ThreadFactorythreadFactory, RejectedExecutionHandlerhandler){ if(corePoolSize<0|| maximumPoolSize<=0|| maximumPoolSize 参数:
1、corePoolSize核心线程数大小,当线程数
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来写拒绝策略.
intcorePoolSize=1; intmaximumPoolSize=2; intkeepAliveTime=10; //BlockingQueueworkQueue=newLinkedBlockingQueue (); BlockingQueue workQueue=newArrayBlockingQueue (5); ThreadFactorythreadFactory=Executors.defaultThreadFactory(); //线程池和队列满了之后的处理方式 //1.跑出异常 RejectedExecutionHandlerhandler=newThreadPoolExecutor.AbortPolicy(); RejectedExecutionHandlerhandler2=newThreadPoolExecutor.CallerRunsPolicy(); RejectedExecutionHandlerhandler3=newThreadPoolExecutor.DiscardPolicy(); RejectedExecutionHandlerhandler4=newThreadPoolExecutor.DiscardOldestPolicy(); ThreadPoolExecutorthreadPoolExecutor=newThreadPoolExecutor(corePoolSize,maximumPoolSize,keepAliveTime,TimeUnit.SECONDS,workQueue,threadFactory,handler2); for(intj=1;j<15;j++){ threadPoolExecutor.execute(newRunnable(){ publicvoidrun(){ try{ System.out.println(Thread.currentThread().getName()); TimeUnit.SECONDS.sleep(1); }catch(InterruptedExceptione){ e.printStackTrace(); } } }); } System.out.println(threadPoolExecutor); } 感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!