使用执行程序和ThreadPoolExecutor的Java线程池示例
線程池管理工作線程池,它包含一個隊列,使任務等待執行。 線程池管理可運行線程的集合,工作線程從隊列中執行可運行線程。 java.util.concurrent.Executors提供java.util.concurrent.Executor接口的實現,以在Java中創建線程池。
讓我們編寫一個簡單的程序來說明它的工作原理。
首先,我們需要有一個Runnable類。
package com.journaldev.threadpool;public class WorkerThread implements Runnable {private String command;public WorkerThread(String s){this.command=s;}@Overridepublic void run() {System.out.println(Thread.currentThread().getName()+' Start. Command = '+command);processCommand();System.out.println(Thread.currentThread().getName()+' End.');}private void processCommand() {try {Thread.sleep(5000);} catch (InterruptedException e) {e.printStackTrace();}}@Overridepublic String toString(){return this.command;} }這是我們從Executors框架創建固定線程池的測試程序。
package com.journaldev.threadpool;import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors;public class SimpleThreadPool {public static void main(String[] args) {ExecutorService executor = Executors.newFixedThreadPool(5);for (int i = 0; i < 10; i++) {Runnable worker = new WorkerThread('' + i);executor.execute(worker);}executor.shutdown();while (!executor.isTerminated()) {}System.out.println('Finished all threads');}}在上面的程序中,我們正在創建5個工作線程的固定大小的線程池。 然后,我們將10個作業提交到該池中,因為該池的大小為5,它將開始處理5個作業,其他作業將處于等待狀態,一旦其中一個作業完成,來自等待隊列的另一個作業將被工作線程拾取并執行。
這是上面程序的輸出。
pool-1-thread-2 Start. Command = 1 pool-1-thread-4 Start. Command = 3 pool-1-thread-1 Start. Command = 0 pool-1-thread-3 Start. Command = 2 pool-1-thread-5 Start. Command = 4 pool-1-thread-4 End. pool-1-thread-5 End. pool-1-thread-1 End. pool-1-thread-3 End. pool-1-thread-3 Start. Command = 8 pool-1-thread-2 End. pool-1-thread-2 Start. Command = 9 pool-1-thread-1 Start. Command = 7 pool-1-thread-5 Start. Command = 6 pool-1-thread-4 Start. Command = 5 pool-1-thread-2 End. pool-1-thread-4 End. pool-1-thread-3 End. pool-1-thread-5 End. pool-1-thread-1 End. Finished all threads輸出確認池中有五個線程來自“ pool-1-thread-1? 到“ pool-1-thread-5”? 他們負責執行提交給池的任務。
Executors類提供簡單實現的ExecutorService的使用的ThreadPoolExecutor但ThreadPoolExecutor的提供了更多的功能不止于此。 我們可以指定創建ThreadPoolExecutor實例時仍處于活動狀態的線程數,并且可以限制線程池的大小,并創建自己的RejectedExecutionHandler實現以處理無法容納在工作隊列中的作業。
這是我們對RejectedExecutionHandler接口的自定義實現。
package com.journaldev.threadpool;import java.util.concurrent.RejectedExecutionHandler; import java.util.concurrent.ThreadPoolExecutor;public class RejectedExecutionHandlerImpl implements RejectedExecutionHandler {@Overridepublic void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {System.out.println(r.toString() + ' is rejected');}}ThreadPoolExecutor提供了幾種方法,通過這些方法我們可以找到執行器的當前狀態,池大小,活動線程數和任務數。 因此,我有一個監視線程,它將在特定時間間隔打印執行程序信息。
package com.journaldev.threadpool;import java.util.concurrent.ThreadPoolExecutor;public class MyMonitorThread implements Runnable {private ThreadPoolExecutor executor;private int seconds;private boolean run=true;public MyMonitorThread(ThreadPoolExecutor executor, int delay){this.executor = executor;this.seconds=delay;}public void shutdown(){this.run=false;}@Overridepublic void run(){while(run){System.out.println(String.format('[monitor] [%d/%d] Active: %d, Completed: %d, Task: %d, isShutdown: %s, isTerminated: %s',this.executor.getPoolSize(),this.executor.getCorePoolSize(),this.executor.getActiveCount(),this.executor.getCompletedTaskCount(),this.executor.getTaskCount(),this.executor.isShutdown(),this.executor.isTerminated()));try {Thread.sleep(seconds*1000);} catch (InterruptedException e) {e.printStackTrace();}}} }這是使用ThreadPoolExecutor的線程池實現示例。
package com.journaldev.threadpool;import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.Executors; import java.util.concurrent.ThreadFactory; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit;public class WorkerPool {public static void main(String args[]) throws InterruptedException{//RejectedExecutionHandler implementationRejectedExecutionHandlerImpl rejectionHandler = new RejectedExecutionHandlerImpl();//Get the ThreadFactory implementation to useThreadFactory threadFactory = Executors.defaultThreadFactory();//creating the ThreadPoolExecutorThreadPoolExecutor executorPool = new ThreadPoolExecutor(2, 4, 10, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(2), threadFactory, rejectionHandler);//start the monitoring threadMyMonitorThread monitor = new MyMonitorThread(executorPool, 3);Thread monitorThread = new Thread(monitor);monitorThread.start();//submit work to the thread poolfor(int i=0; i<10; i++){executorPool.execute(new WorkerThread('cmd'+i));}Thread.sleep(30000);//shut down the poolexecutorPool.shutdown();//shut down the monitor threadThread.sleep(5000);monitor.shutdown();} }請注意,在初始化ThreadPoolExecutor時,我們將初始池大小保持為2,最大池大小保持為4,工作隊列大小保持為2。因此,如果有4個正在運行的任務并且提交了更多任務,則工作隊列將僅容納其中2個其余的將由RejectedExecutionHandlerImpl處理。
這是上述程序的輸出,確認上述聲明。
pool-1-thread-1 Start. Command = cmd0 pool-1-thread-4 Start. Command = cmd5 cmd6 is rejected pool-1-thread-3 Start. Command = cmd4 pool-1-thread-2 Start. Command = cmd1 cmd7 is rejected cmd8 is rejected cmd9 is rejected [monitor] [0/2] Active: 4, Completed: 0, Task: 6, isShutdown: false, isTerminated: false [monitor] [4/2] Active: 4, Completed: 0, Task: 6, isShutdown: false, isTerminated: false pool-1-thread-4 End. pool-1-thread-1 End. pool-1-thread-2 End. pool-1-thread-3 End. pool-1-thread-1 Start. Command = cmd3 pool-1-thread-4 Start. Command = cmd2 [monitor] [4/2] Active: 2, Completed: 4, Task: 6, isShutdown: false, isTerminated: false [monitor] [4/2] Active: 2, Completed: 4, Task: 6, isShutdown: false, isTerminated: false pool-1-thread-1 End. pool-1-thread-4 End. [monitor] [4/2] Active: 0, Completed: 6, Task: 6, isShutdown: false, isTerminated: false [monitor] [2/2] Active: 0, Completed: 6, Task: 6, isShutdown: false, isTerminated: false [monitor] [2/2] Active: 0, Completed: 6, Task: 6, isShutdown: false, isTerminated: false [monitor] [2/2] Active: 0, Completed: 6, Task: 6, isShutdown: false, isTerminated: false [monitor] [2/2] Active: 0, Completed: 6, Task: 6, isShutdown: false, isTerminated: false [monitor] [2/2] Active: 0, Completed: 6, Task: 6, isShutdown: false, isTerminated: false [monitor] [0/2] Active: 0, Completed: 6, Task: 6, isShutdown: true, isTerminated: true [monitor] [0/2] Active: 0, Completed: 6, Task: 6, isShutdown: true, isTerminated: true 注意執行程序的活動,已完成和已完成任務總數的變化。 我們可以調用shutdown()方法來完成所有提交的任務的執行并終止線程池。
參考: Java線程池示例,使用我們的JCG合作伙伴 Pankaj Kumar的Executors和ThreadPoolExecutor ,位于Developer Recipes博客上。
翻譯自: https://www.javacodegeeks.com/2013/01/java-thread-pool-example-using-executors-and-threadpoolexecutor.html
總結
以上是生活随笔為你收集整理的使用执行程序和ThreadPoolExecutor的Java线程池示例的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: IntelliJ IDEA:使用Goog
- 下一篇: 防ddos的防火墙(防ddos的cdn)