JAVA之執行緒池
一、執行緒池的概念
執行緒池,其實就是一個容納多個執行緒的容器,其中的執行緒可以反覆使用,省去了頻繁建立執行緒物件的操作,無需反覆建立執行緒而消耗過多資源。
圖解:
二、使用執行緒池方式
1、Runable介面:
通常,執行緒池都是通過執行緒池工廠建立,再呼叫執行緒池中的方法獲取執行緒,再通過執行緒去執行任務方法。
Executors:執行緒池建立工廠類
public static ExecutorService newFixedThreadPool(int nThreads):返回執行緒池物件
ExecutorService:執行緒池類
Future<?> submit(Runnabletask):獲取執行緒池中的某一個執行緒物件,並執行
Future介面:用來記錄執行緒任務執行完畢後產生的結果。執行緒池建立與使用
使用執行緒池中執行緒物件的步驟:
建立執行緒池物件
建立Runnable介面子類物件
提交Runnable介面子類物件
關閉執行緒池
public class ThreadPoolDemo { public static void main(String[] args) { //建立執行緒池物件 ExecutorService service = Executors.newFixedThreadPool(2);//包含2個執行緒物件 //建立Runnable例項物件 MyRunnable r = newMyRunnable(); //自己建立執行緒物件的方式 //Thread t = new Thread(r); //t.start(); ---> 呼叫MyRunnable中的run() //從執行緒池中獲取執行緒物件,然後呼叫MyRunnable中的run() service.submit(r); //再獲取個執行緒物件,呼叫MyRunnable中的run() service.submit(r); service.submit(r); //注意:submit方法呼叫結束後,程式並不終止,是因為執行緒池控制了執行緒的關閉。將使用完的執行緒又歸還到了執行緒池中//關閉執行緒池 //service.shutdown(); } }
Runable介面實現類:
public class MyRunnable implements Runnable { @Override public void run() { System.out.println("我要一個教練"); try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("教練來了: " +Thread.currentThread().getName()); System.out.println("教我游泳,交完後,教練回到了游泳池"); } }
2、Callable介面
lCallable介面:與Runnable介面功能相似,用來指定執行緒的任務。其中的call()方法,用來返回執行緒任務執行完畢後的結果,call方法可丟擲異常。
lExecutorService:執行緒池類
n<T> Future<T> submit(Callable<T>task):獲取執行緒池中的某一個執行緒物件,並執行執行緒中的call()方法
lFuture介面:用來記錄執行緒任務執行完畢後產生的結果。執行緒池建立與使用
l使用執行緒池中執行緒物件的步驟:
n建立執行緒池物件
n建立Callable介面子類物件
n提交Callable介面子類物件
n關閉執行緒池
public class ThreadPoolDemo { public static void main(String[] args) { //建立執行緒池物件 ExecutorService service = Executors.newFixedThreadPool(2);//包含2個執行緒物件 //建立Callable物件 MyCallable c = new MyCallable(); //從執行緒池中獲取執行緒物件,然後呼叫MyRunnable中的run() service.submit(c); //再獲取個教練 service.submit(c); service.submit(c); //注意:submit方法呼叫結束後,程式並不終止,是因為執行緒池控制了執行緒的關閉。將使用完的執行緒又歸還到了執行緒池中 //關閉執行緒池 //service.shutdown(); } }
Callable介面實現類,call方法可丟擲異常、返回執行緒任務執行完畢後的結果
public class MyCallable implements Callable { @Override public Object call() throws Exception { System.out.println("我要一個教練:call"); Thread.sleep(2000); System.out.println("教練來了: " +Thread.currentThread().getName()); System.out.println("教我游泳,交完後,教練回到了游泳池"); return null; } }