http://heipark.iteye.com/blog/1393847
newFixedThreadPool內部有個任務隊列,假設線程池里有3個線程,提交了5個任務,那么后兩個任務就放在任務隊列了,即使前3個任務sleep或者堵塞了,也不會執行后兩個任務,除非前三個任務有執行完的
newFixedThreadPool使用范例:
?
?
?
Java代碼??
import ?java.io.IOException;?? import ?java.util.concurrent.ExecutorService;?? import ?java.util.concurrent.Executors;?? ?? public ?class ?Test?{?? ?? ????public ?static ?void ?main(String[]?args)?throws ?IOException,?InterruptedException?{?? ????????ExecutorService?service?=?Executors.newFixedThreadPool(2 );?? ????????for ?(int ?i?=?0 ;?i?<?6 ;?i++)?{?? ????????????final ?int ?index?=?i;?? ????????????System.out.println("task:?" ?+?(i+1 ));?? ????????????Runnable?run?=?new ?Runnable()?{?? ????????????????@Override ?? ????????????????public ?void ?run()?{?? ????????????????????System.out.println("thread?start" ?+?index);?? ????????????????????try ?{?? ????????????????????????Thread.sleep(Long.MAX_VALUE);?? ????????????????????}?catch ?(InterruptedException?e)?{?? ????????????????????????e.printStackTrace();?? ????????????????????}?? ????????????????????System.out.println("thread?end" ?+?index);?? ????????????????}?? ????????????};?? ????????????service.execute(run);?? ????????}?? ????}?? }??
?
輸出:
task: 1
task: 2
thread start0
task: 3
task: 4
task: 5
task: 6
task: 7
thread start1
task: 8
task: 9
task: 10
task: 11
task: 12
task: 13
task: 14
task: 15
?
? ? 從實例可以看到for循環并沒有被固定的線程池阻塞住,也就是說所有的線程task都被提交到了ExecutorService中,查看?Executors.newFixedThreadPool()如下:
?
?
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
}
? ? 可以看到task被提交都了LinkedBlockingQueue中。這里有個問題,如果任務列表很大,一定會把內存撐爆,如何解決?看下面:
?
?
Java代碼??
import ?java.io.IOException;?? import ?java.util.concurrent.ArrayBlockingQueue;?? import ?java.util.concurrent.BlockingQueue;?? import ?java.util.concurrent.ThreadPoolExecutor;?? import ?java.util.concurrent.TimeUnit;?? ?? public ?class ?Test?{?? ?? ????public ?static ?void ?main(String[]?args)?throws ?IOException,?InterruptedException?{?? ?????????? ????????BlockingQueue<Runnable>?queue?=?new ?ArrayBlockingQueue<Runnable>(3 );?? ?????????? ????????ThreadPoolExecutor?executor?=?new ?ThreadPoolExecutor(3 ,?3 ,?1 ,?TimeUnit.HOURS,?queue,?new ?ThreadPoolExecutor.CallerRunsPolicy());?? ?????????? ????????for ?(int ?i?=?0 ;?i?<?10 ;?i++)?{?? ????????????final ?int ?index?=?i;?? ????????????System.out.println("task:?" ?+?(index+1 ));?? ????????????Runnable?run?=?new ?Runnable()?{?? ????????????????@Override ?? ????????????????public ?void ?run()?{?? ????????????????????System.out.println("thread?start" ?+?(index+1 ));?? ????????????????????try ?{?? ????????????????????????Thread.sleep(Long.MAX_VALUE);?? ????????????????????}?catch ?(InterruptedException?e)?{?? ????????????????????????e.printStackTrace();?? ????????????????????}?? ????????????????????System.out.println("thread?end" ?+?(index+1 ));?? ????????????????}?? ????????????};?? ????????????executor.execute(run);?? ????????}?? ????}?? }??
?
輸出:
task: 1
task: 2
thread start1
task: 3
task: 4
task: 5
task: 6
task: 7
thread start2
thread start7
thread start6
?
? ? 線程池最大值為4(??這里我不明白為什么是設置值+1,即3+1,而不是3),準備執行的任務隊列為3。可以看到for循環先處理4個task,然后把3個放到隊列。這樣就實現了自動阻塞隊列的效果。記得要使用ArrayBlockingQueue這個隊列,然后設置容量就OK了。
總結
以上是生活随笔 為你收集整理的Executors.newFixedThreadPool和ArrayBlockingQueue一点使用心得 的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔 網站內容還不錯,歡迎將生活随笔 推薦給好友。