十年网站开发经验 + 多家企业客户 + 靠谱的建站团队
量身定制 + 运营维护+专业推广+无忧售后,网站问题一站解决
这篇文章主要讲解了“线程池ThreadPoolExecutor有什么作用”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“线程池ThreadPoolExecutor有什么作用”吧!
创新互联专注于岳塘网站建设服务及定制,我们拥有丰富的企业做网站经验。 热诚为您提供岳塘营销型网站建设,岳塘网站制作、岳塘网页设计、岳塘网站官网定制、小程序开发服务,打造岳塘网络公司原创品牌,更为您提供岳塘网站排名全网营销落地服务。
一、初始化线程池(4种):
1、newFixedThreadPool()
public final static ExecutorService esPool = Execustor.newFixedThreadPool(50);
特点:corePoolSize == maxPoolSize,使用LinkedBlockingQueue作为堵塞队列;没有可执行任务时不会释放线程池;
2、newCachedThreadPool()
public final static ExecutorService esPool = Execustor.newCachedThreadPool();
特点:默认缓存60s,线程数可以达到Integer.MAX_VALUE,内部使用SynchronousQueue作为堵塞队列;没有可执行任务时,达到keepAliveTime会释放线程资源,新任务没有执行空闲线程就得重新创建新的线程,会导致系统开销;使用时,注意控制并发数,减少创建新线程数;
3、newScheduleThreadPool()
public final static ExecutorService esPool = Execustor.newScheduleThreadPool(50);
特点:指定时间内周期性内执行所提交的任务,一般用于定时同步数据;
4、newSingleThreadExecutor()
特点:初始化只有一个线程的线程池;内部使用LinkedBlockingQueue作为堵塞队列;
二、源码实现:
1、ThreadPoolExecutor构造器
public ThreadPoolExecutor( int corePoolSize,//核心线程数 int maximumPoolSize,//最大线程数 long keepAliveTime,//线程存活时间(必须在线程数在corePoolSize与maximumPoolSie之间时,存活时间才能生效) TimeUnit unit,//存活时间的单位 BlockingQueueworkQueue,//堵塞队列 RejectedExecutionHandler handler//当拒绝处理任务时的策略 ) { this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, Executors.defaultThreadFactory(), handler); }
说明:堵塞队列BlockingQueue:1)ArrayBlockingQueue(数组结构的界限堵塞队列,FIFO);2)LinkedBlockQueue(链表结构的堵塞队列,FIFO);3)SynchronousQueue(不存储元素的堵塞队列,每次插入必须等到另一个线程移除);4)PriorityBlockingQueue(具有优先级的堵塞队列)。
拒绝处理任务的策略RejectedExecutionHandler:1)、ThreadPoolExecutor.AbortPolicy(抛弃当前线程,并抛出RejectedExecutionException异常)2)、ThreadPoolExecutor.DiscardPolicy(抛弃当前线程,不抛出异常);3)、ThreadPoolExecutor.DiscardOldestPolicy(抛弃最前面的任务,然后重新尝试此执行过程);4)、CallerRunnsPolicy(调用线程执行此任务)
2、execute()
public void execute(Runnable command) { if (command == null) throw new NullPointerException(); int c = ctl.get(); //获取当前线程的数量:workerCountOf() if (workerCountOf(c) < corePoolSize) { if (addWorker(command, true))//当当前线程数量小于corePoolSize时,就addWorker return; c = ctl.get(); } //如果当前线程处于Running状态; if (isRunning(c) && workQueue.offer(command)) { int recheck = ctl.get(); //检查线程池(因为可能在上次检查后,有线程资源被释放),是否有空闲的线程 if (! isRunning(recheck) && remove(command)) reject(command); else if (workerCountOf(recheck) == 0) addWorker(null, false); } //如果当前线程处于非Running状态; else if (!addWorker(command, false)) reject(command); }
3、reject()
final void reject(Runnable command) { handler.rejectedExecution(command, this); }
4、submit()
publicFuture submit(Callable task) { if (task == null) throw new NullPointerException(); //封装成一个FutureTask对象,FutureTask类实现Runnable接口 RunnableFuture ftask = newTaskFor(task); //执行execute(),通过execute提交到FutureTask线程池中等待被执行,最终执行FutureTask的run方法 execute(ftask); return ftask; } protected RunnableFuture newTaskFor(Callable callable) { return new FutureTask (callable); }
5、线程状态
private static final int COUNT_BITS = Integer.SIZE - 3; //即高3位为111,该状态的线程池会接收新任务,并处理阻塞队列中的任务; private static final int RUNNING = -1 << COUNT_BITS; //即高3位为000,该状态的线程池不会接收新任务,但会处理阻塞队列中的任务; private static final int SHUTDOWN = 0 << COUNT_BITS; //即高3位为001,该状态的线程不会接收新任务,也不会处理阻塞队列中的任务,而且会中断正在运行的任务; private static final int STOP = 1 << COUNT_BITS; //即高3位为010,该状态表示线程池对线程进行整理优化; private static final int TIDYING = 2 << COUNT_BITS; //即高3位为011,该状态表示线程池停止工作; private static final int TERMINATED = 3 << COUNT_BITS;
6、runWorker()(真正执行任务的接口)
final void runWorker(Worker w) { Thread wt = Thread.currentThread(); Runnable task = w.firstTask; w.firstTask = null; w.unlock(); // allow interrupts boolean completedAbruptly = true; try { while (task != null || (task = getTask()) != null) { w.lock(); // If pool is stopping, ensure thread is interrupted; // if not, ensure thread is not interrupted. This // requires a recheck in second case to deal with // shutdownNow race while clearing interrupt if ((runStateAtLeast(ctl.get(), STOP) || (Thread.interrupted() && runStateAtLeast(ctl.get(), STOP))) && !wt.isInterrupted()) wt.interrupt(); try { beforeExecute(wt, task); Throwable thrown = null; try { task.run(); } catch (RuntimeException x) { thrown = x; throw x; } catch (Error x) { thrown = x; throw x; } catch (Throwable x) { thrown = x; throw new Error(x); } finally { afterExecute(task, thrown);//啥都没做 } } finally { task = null; w.completedTasks++; w.unlock(); } } completedAbruptly = false; } finally { processWorkerExit(w, completedAbruptly); } } protected void afterExecute(Runnable r, Throwable t) { }
感谢各位的阅读,以上就是“线程池ThreadPoolExecutor有什么作用”的内容了,经过本文的学习后,相信大家对线程池ThreadPoolExecutor有什么作用这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是创新互联,小编将为大家推送更多相关知识点的文章,欢迎关注!