ThreadPoolExecutor提供了两个方法,用于线程池的关闭,分别是shutdown()和shutdownNow():
public void shutdown() { final ReentrantLock mainLock = this.mainLock; mainLock.lock(); try { checkShutdownAccess(); advanceRunState(SHUTDOWN); interruptIdleWorkers(); onShutdown(); // hook for ScheduledThreadPoolExecutor } finally { mainLock.unlock(); } tryTerminate(); } public List<Runnable> shutdownNow() { List<Runnable> tasks; final ReentrantLock mainLock = this.mainLock; mainLock.lock(); try { checkShutdownAccess(); advanceRunState(STOP); interruptWorkers(); tasks = drainQueue(); } finally { mainLock.unlock(); } tryTerminate(); return tasks; }代码逻辑就不一一进行解析了,总结一下两个方法的特点就是:
shutdown():不会立即终止线程池,而是要等所有任务缓存队列中的任务都执行完后才终止,但再也不会接受新的任务
shutdownNow():立即终止线程池,并尝试打断正在执行的任务,并且清空任务缓存队列,返回尚未执行的任务
ThreadPoolExecutor创建线程池实例ThreadPoolExecutor的运行机制讲完了,接下来展示一下如何用ThreadPoolExecutor创建线程池实例,具体代码如下:
public static void main(String[] args) { ExecutorService service = new ThreadPoolExecutor(5, 10, 300, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(5)); //用lambda表达式编写方法体中的逻辑 Runnable run = () -> { try { Thread.sleep(1000); System.out.println(Thread.currentThread().getName() + "正在执行"); } catch (InterruptedException e) { e.printStackTrace(); } }; for (int i = 0; i < 10; i++) { service.execute(run); } //这里一定要做关闭 service.shutdown(); }上面的代码中,我们创建的ThreadPoolExecutor线程池的核心线程数为5个,所以,当调用线程池执行任务时,同时运行的线程最多也是5个,执行main方法,输出结果如下:
pool-1-thread-3正在执行 pool-1-thread-1正在执行 pool-1-thread-4正在执行 pool-1-thread-5正在执行 pool-1-thread-3正在执行 pool-1-thread-2正在执行 pool-1-thread-1正在执行 pool-1-thread-4正在执行 pool-1-thread-5正在执行看到出来,线程池确实只有5个线程在工作,也就是真正的实现了线程的复用,说明我们的ThreadPoolExecutor实例是有效的。
参考:https://www.cnblogs.com/liuzhihu/p/8177371.html
https://www.cnblogs.com/dolphin0520/p/3932921.html
《实战Java:高并发程序设计》