Java多執行緒之~~~使用ThreadPoolExecutor來建立執行緒
阿新 • • 發佈:2019-01-17
以前我們建立執行緒的時候都是主動的new一個Thread,然後呼叫他們的start方法,但是如果執行緒非常多,任務也非
常多的時候,這樣寫就會顯得非常麻煩,當然可能效率也不是很高,Java給我們提供了叫執行緒建立器這個樣概念的類,
他可以幫助我們管理這些執行緒,你做的就是編寫好程式碼,然後交給他,她就會自動幫你執行。
當然,帶cache的threadpool 對於死掉的執行緒重新呼叫,在效能上也會有非常好的表現,但是不能將太多的執行緒交
給他管理,否則就會把系統拖垮,下面我們來做一個例子。
package com.bird.concursey.charpet6; import java.util.Date; import java.util.concurrent.TimeUnit; public class Task implements Runnable { // store the creation date of the task private Date initDate; // store the name of the task private String name; public Task(String name) { this.initDate = new Date(); this.name = name; } @Override public void run() { System.out.printf("%s: Task %s: Created on: %s\n", Thread .currentThread().getName(), name, initDate); System.out.printf("%s: Task %s: Started on: %s\n", Thread .currentThread().getName(), name, new Date()); try { Long duration = (long) (Math.random() * 10); System.out.printf("%s: Task %s: Doing a task during %d seconds\n", Thread.currentThread().getName(), name, duration); TimeUnit.SECONDS.sleep(duration); } catch (InterruptedException e) { e.printStackTrace(); } System.out.printf("%s: Task %s: Finished on: %s\n",Thread. currentThread().getName(),name,new Date()); } }
package com.bird.concursey.charpet6; import java.util.concurrent.Executors; import java.util.concurrent.ThreadPoolExecutor; /** * execute every task it receives using an executor * * @author bird 2014年9月23日 下午9:03:01 */ public class Server { private ThreadPoolExecutor executor; public Server() { executor = (ThreadPoolExecutor) Executors.newCachedThreadPool(); } public void executeTask(Task task) { System.out.printf("Server: A new task has arrived\n"); executor.execute(task); System.out.printf("Server: Pool Size: %d\n", executor.getPoolSize()); System.out.printf("Server: Active Count: %d\n", executor.getActiveCount()); System.out.printf("Server: Completed Tasks: %d\n", executor.getCompletedTaskCount()); } public void endServer() { executor.shutdown(); } public static void main(String[] args) { Server server = new Server(); for(int i = 0; i < 100; i++) { Task task = new Task("Task" + i); server.executeTask(task); } server.endServer(); } }
如果有大量的執行緒進入,他會給每一個執行緒建立一個物件,這樣就會令系統不堪重負,Executors提供了一種構造方
法,設定一個最大量,如果建立的執行緒數量超過了這個數量,Executors就不會再去建立這個執行緒,等待已經線上程池
裡面的執行緒執行完了,有空閒的位置了才去繼續建立新執行緒,這樣就會讓系統變的健壯。
上面的程式碼都不需要該,我們只需要在建構函式的地方重新例項化一個程式碼如下
public Server() {
executor = (ThreadPoolExecutor) Executors.newFixedThreadPool(5);
}