多線程簡單實例(3)線程池
為什麽要用線程池?
每次用線程的時候都去new一個,不麻煩麽。如果線程用到較少可以。當需要大量用到線程時,頻繁的創建線程,而且創建線程和銷毀帶來的開銷也會隨之增多。
線程池就像一個執行器。而我們需要執行的業務邏輯,在我們編寫的實現了Runnable接口的run方法裏面。
需要執行就扔到線程池裏,我只要保證我的業務邏輯在run裏面已經實現了。執行找線程池這個代工。
線程池ThreadPoolExecutor類,下面是該類的構造方法。
public class ThreadPoolExecutor extends AbstractExecutorService { ..... publicThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit, BlockingQueue<Runnable> workQueue); public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit, BlockingQueue<Runnable> workQueue,ThreadFactory threadFactory);public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit, BlockingQueue<Runnable> workQueue,RejectedExecutionHandler handler); public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit, BlockingQueue<Runnable> workQueue,ThreadFactory threadFactory,RejectedExecutionHandler handler); ... }
主要參數介紹:
corePoolSize:核心線程數
maximumPoolSize:最大線程數(可以想象成cpu中的超超頻)
keepAliveTime:線程無任務存活時間(一般情況下,當前線程數poolSize大於corePoolSize時,會銷毀空閑時間大於keepAliveTime的線程,直到當前線程數不大於corePoolSize)
unit:keepAliveTime的單位(
TimeUnit.DAYS; //天 TimeUnit.HOURS; //小時 TimeUnit.MINUTES; //分鐘 TimeUnit.SECONDS; //秒 TimeUnit.MILLISECONDS; //毫秒 TimeUnit.MICROSECONDS; //微妙 TimeUnit.NANOSECONDS; //納秒
)
BlockingQueue<Runnable>:緩存隊列中允許最大的任務線程數(當線程數大於maxnumPoolSize時,將加入到緩存隊列中)
ThreaPoolExecutor的一些方法:
execute():線程池加入線程
submit():線程池加入線程(和execute方法一樣,只不過會返回一個參數。ps:其實submit內部也是調用了execute方法)
shutdown():關閉線程池(若線程池和緩存中還有未執行完的線程,則會繼續執行,執行完清空線程池。)
shutdownNow():馬上關閉線程池(若線程池中還有未執行完的線程,則會拋出異常)
簡單的例子:
package code.thread; import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; //線程池 public class ThreadPool { public static void main(String[] args) { ThreadPoolExecutor threadPool = new ThreadPoolExecutor(5, 10, 200, TimeUnit.MICROSECONDS, new ArrayBlockingQueue<Runnable>(5)); for(int i=0;i<15;i++){ threadPool.execute(new Task(i)); System.out.println("線程池中的線程數:"+threadPool.getPoolSize()+" 隊列中等待的線程數:"+ threadPool.getQueue().size()+" 已執行完的線程數:"+threadPool.getCompletedTaskCount()); } { try { Thread.sleep(5000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println("線程池中的線程數:"+threadPool.getPoolSize()+" 隊列中等待的線程數:"+ threadPool.getQueue().size()+" 已執行完的線程數:"+threadPool.getCompletedTaskCount()); } threadPool.shutdown(); } } class Task implements Runnable { private int i; public Task(int i) { this.i = i; } @Override public void run() { System.out.println("task:"+i+"執行"); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("task:"+i+"執行結束"); } }
執行結果:
task:0執行
線程池中的線程數:1 隊列中等待的線程數:0 已執行完的線程數:0
線程池中的線程數:2 隊列中等待的線程數:0 已執行完的線程數:0
task:1執行
線程池中的線程數:3 隊列中等待的線程數:0 已執行完的線程數:0
task:2執行
線程池中的線程數:4 隊列中等待的線程數:0 已執行完的線程數:0
task:3執行
線程池中的線程數:5 隊列中等待的線程數:0 已執行完的線程數:0
task:4執行
線程池中的線程數:5 隊列中等待的線程數:1 已執行完的線程數:0
線程池中的線程數:5 隊列中等待的線程數:2 已執行完的線程數:0
線程池中的線程數:5 隊列中等待的線程數:3 已執行完的線程數:0
線程池中的線程數:5 隊列中等待的線程數:4 已執行完的線程數:0
線程池中的線程數:5 隊列中等待的線程數:5 已執行完的線程數:0
線程池中的線程數:6 隊列中等待的線程數:5 已執行完的線程數:0
task:10執行
線程池中的線程數:7 隊列中等待的線程數:5 已執行完的線程數:0
task:11執行
task:12執行
線程池中的線程數:8 隊列中等待的線程數:5 已執行完的線程數:0
線程池中的線程數:9 隊列中等待的線程數:5 已執行完的線程數:0
task:13執行
task:14執行
線程池中的線程數:10 隊列中等待的線程數:5 已執行完的線程數:0
task:0執行結束
task:2執行結束
task:5執行
task:1執行結束
task:6執行
task:3執行結束
task:8執行
task:4執行結束
task:9執行
task:13執行結束
task:7執行
task:10執行結束
task:11執行結束
task:12執行結束
task:14執行結束
task:5執行結束
task:6執行結束
task:7執行結束
task:9執行結束
task:8執行結束
線程池中的線程數:5 隊列中等待的線程數:0 已執行完的線程數:15
多線程簡單實例(3)線程池