国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

newFixedThreadPool

2019-11-15 01:02:06
字體:
來源:轉載
供稿:網友
newFixedThreadPool

newFixedThreadPool內部有個任務隊列,假設線程池里有3個線程,提交了5個任務,那么后兩個任務就放在任務隊列了,即使前3個任務sleep或者堵塞了,也不會執行后兩個任務,除非前三個任務有執行完的

newFixedThreadPool使用范例:

java代碼收藏代碼
  1. importjava.io.IOException;
  2. importjava.util.concurrent.ExecutorService;
  3. importjava.util.concurrent.Executors;
  4. publicclassTest{
  5. publicstaticvoidmain(String[]args)throwsIOException,InterruptedException{
  6. ExecutorServiceservice=Executors.newFixedThreadPool(2);
  7. for(inti=0;i<6;i++){
  8. finalintindex=i;
  9. System.out.
  10. }
  11. };
  12. service.execute(run);
  13. }
  14. }
  15. }

輸出:task: 1task: 2thread start0task: 3task: 4task: 5task: 6task: 7thread start1task: 8task: 9task: 10task: 11task: 12task: 13task: 14task: 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代碼收藏代碼
  1. importjava.io.IOException;
  2. importjava.util.concurrent.ArrayBlockingQueue;
  3. importjava.util.concurrent.BlockingQueue;
  4. importjava.util.concurrent.ThreadPoolExecutor;
  5. importjava.util.concurrent.TimeUnit;
  6. publicclassTest{
  7. publicstaticvoidmain(String[]args)throwsIOException,InterruptedException{
  8. BlockingQueue<Runnable>queue=newArrayBlockingQueue<Runnable>(3);
  9. ThreadPoolExecutorexecutor=newThreadPoolExecutor(3,3,1,TimeUnit.HOURS,queue,newThreadPoolExecutor.CallerRunsPolicy());
  10. for(inti=0;i<10;i++){
  11. finalintindex=i;
  12. System.out.println("task:"+(index+1));
  13. Runnablerun=newRunnable(){
  14. @Override
  15. publicvoidrun(){
  16. System.out.println("threadstart"+(index+1));
  17. try{
  18. Thread.sleep(Long.MAX_VALUE);
  19. }catch(InterruptedExceptione){
  20. e.printStackTrace();
  21. }
  22. System.out.println("threadend"+(index+1));
  23. }
  24. };
  25. executor.execute(run);
  26. }
  27. }
  28. }

輸出:task: 1task: 2thread start1task: 3task: 4task: 5task: 6task: 7thread start2thread start7thread start6

線程池最大值為4(??這里我不明白為什么是設置值+1,即3+1,而不是3),準備執行的任務隊列為3。可以看到for循環先處理4個task,然后把3個放到隊列。這樣就實現了自動阻塞隊列的效果。記得要使用ArrayBlockingQueue這個隊列,然后設置容量就OK了。

一、簡介線程池類為 java.util.concurrent.ThreadPoolExecutor,常用構造方法為:ThreadPoolExecutor(int corePoolSize, int maximumPoolSize,long keepAliveTime, TimeUnit unit,BlockingQueueworkQueue,RejectedExecutionHandler handler)corePoolSize: 線程池維護線程的最少數量maximumPoolSize:線程池維護線程的最大數量keepAliveTime: 線程池維護線程所允許的空閑時間unit: 線程池維護線程所允許的空閑時間的單位workQueue: 線程池所使用的緩沖隊列handler: 線程池對拒絕任務的處理策略一個任務通過 execute(Runnable)方法被添加到線程池,任務就是一個 Runnable類型的對象,任務的執行方法就是 Runnable類型對象的run()方法。當一個任務通過execute(Runnable)方法欲添加到線程池時:如果此時線程池中的數量小于corePoolSize,即使線程池中的線程都處于空閑狀態,也要創建新的線程來處理被添加的任務。如果此時線程池中的數量等于 corePoolSize,但是緩沖隊列 workQueue未滿,那么任務被放入緩沖隊列。如果此時線程池中的數量大于corePoolSize,緩沖隊列workQueue滿,并且線程池中的數量小于maximumPoolSize,建新的線程來處理被添加的任務。如果此時線程池中的數量大于corePoolSize,緩沖隊列workQueue滿,并且線程池中的數量等于maximumPoolSize,那么通過 handler所指定的策略來處理此任務。也就是:處理任務的優先級為:核心線程corePoolSize、任務隊列workQueue、最大線程maximumPoolSize,如果三者都滿了,使用handler處理被拒絕的任務。當線程池中的線程數量大于 corePoolSize時,如果某線程空閑時間超過keepAliveTime,線程將被終止。這樣,線程池可以動態的調整池中的線程數。unit可選的參數為java.util.concurrent.TimeUnit中的幾個靜態屬性:NANOSECONDS、MICROSECONDS、MILLISECONDS、SECONDS。workQueue我常用的是:java.util.concurrent.ArrayBlockingQueuehandler有四個選擇:ThreadPoolExecutor.AbortPolicy()拋出java.util.concurrent.RejectedExecutionException異常ThreadPoolExecutor.CallerRunsPolicy()重試添加當前的任務,他會自動重復調用execute()方法ThreadPoolExecutor.DiscardOldestPolicy()拋棄舊的任務ThreadPoolExecutor.DiscardPolicy()拋棄當前的任務二、一般用法舉例

點擊(此處)折疊或打開

  1. packagedemo;
  2. importjava.io.Serializable;
  3. importjava.util.concurrent.ArrayBlockingQueue;
  4. importjava.util.concurrent.ThreadPoolExecutor;
  5. importjava.util.concurrent.TimeUnit;
  6. publicclassTestThreadPool2
  7. {
  8. privatestaticintproduceTaskSleepTime=2;
  9. privatestaticintproduceTaskMaxNumber=10;
  10. publicstaticvoidmain(String[]args)
  11. {
  12. // 構造一個線程池
  13. ThreadPoolExecutorthreadPool=newThreadPoolExecutor(2,4,3,TimeUnit.SECONDS,newArrayBlockingQueue<Runnable>(3),
  14. newThreadPoolExecutor.DiscardOldestPolicy());
  15. for(inti=1;i<=produceTaskMaxNumber;i++)
  16. {
  17. try
  18. {
  19. // 產生一個任務,并將其加入到線程池
  20. Stringtask="task@ "+i;
  21. System.out.println("put "+task);
  22. threadPool.execute(newThreadPoolTask(task));
  23. // 便于觀察,等待一段時間
  24. Thread.sleep(produceTaskSleepTime);
  25. }
  26. catch(Exceptione)
  27. {
  28. e.printStackTrace();
  29. }
  30. }
  31. }
  32. }
  33. /**
  34. * 線程池執行的任務
  35. */
  36. classThreadPoolTaskimplementsRunnable,Serializable
  37. {
  38. privatestaticfinallongserialVersionUID=0;
  39. privatestaticintconsumeTaskSleepTime=2000;
  40. // 保存任務所需要的數據
  41. privateObjectthreadPoolTaskData;
  42. ThreadPoolTask(Objecttasks)
  43. {
  44. this.threadPoolTaskData=tasks;
  45. }
  46. publicvoidrun()
  47. {
  48. // 處理一個任務,這里的處理方式太簡單了,僅僅是一個打印語句
  49. System.out.println(Thread.currentThread().getName());
  50. System.out.println("start .."+threadPoolTaskData);
  51. try
  52. {
  53. // //便于觀察,等待一段時間
  54. Thread.sleep(consumeTaskSleepTime);
  55. }
  56. catch(Exceptione)
  57. {
  58. e.printStackTrace();
  59. }
  60. threadPoolTaskData=null;
  61. }
  62. publicObjectgetTask()
  63. {
  64. returnthis.threadPoolTaskData;
  65. }
  66. }

說明:1、在這段程序中,一個任務就是一個Runnable類型的對象,也就是一個ThreadPoolTask類型的對象。2、一般來說任務除了處理方式外,還需要處理的數據,處理的數據通過構造方法傳給任務。3、在這段程序中,main()方法相當于一個殘忍的領導,他派發出許多任務,丟給一個叫 threadPool的任勞任怨的小組來做。這個小組里面隊員至少有兩個,如果他們兩個忙不過來,任務就被放到任務列表里面。如果積壓的任務過多,多到任務列表都裝不下(超過3個)的時候,就雇傭新的隊員來幫忙。但是基于成本的考慮,不能雇傭太多的隊員,至多只能雇傭 4個。如果四個隊員都在忙時,再有新的任務,這個小組就處理不了了,任務就會被通過一種策略來處理,我們的處理方式是不停的派發,直到接受這個任務為止(更殘忍!呵呵)。因為隊員工作是需要成本的,如果工作很閑,閑到 3SECONDS都沒有新的任務了,那么有的隊員就會被解雇了,但是,為了小組的正常運轉,即使工作再閑,小組的隊員也不能少于兩個。4、通過調整 produceTaskSleepTime和 consumeTaskSleepTime的大小來實現對派發任務和處理任務的速度的控制,改變這兩個值就可以觀察不同速率下程序的工作情況。5、通過調整4中所指的數據,再加上調整任務丟棄策略,換上其他三種策略,就可以看出不同策略下的不同處理方式。6、對于其他的使用方法,參看jdk的幫助,很容易理解和使用。另一個例子:

點擊(此處)折疊或打開

  1. packagedemo;
  2. importjava.util.Queue;
  3. importjava.util.concurrent.ArrayBlockingQueue;
  4. importjava.util.concurrent.ThreadPoolExecutor;
  5. importjava.util.concurrent.TimeUnit;
  6. publicclassThreadPoolExecutorTest
  7. {
  8. privatestaticintqueueDeep=4;
  9. publicvoidcreateThreadPool()
  10. {
  11. /*
  12. * 創建線程池,最小線程數為2,最大線程數為4,線程池維護線程的空閑時間為3秒,
  13. * 使用隊列深度為4的有界隊列,如果執行程序尚未關閉,則位于工作隊列頭部的任務將被刪除,
  14. * 然后重試執行程序(如果再次失敗,則重復此過程),里面已經根據隊列深度對任務加載進行了控制。
  15. */
  16. ThreadPoolExecutortpe=newThreadPoolExecutor(2,4,3,TimeUnit.SECONDS,newArrayBlockingQueue<Runnable>(queueDeep),
  17. newThreadPoolExecutor.DiscardOldestPolicy());
  18. // 向線程池中添加 10 個任務
  19. for(inti=0;i<10;i++)
  20. {
  21. try
  22. {
  23. Thread.sleep(1);
  24. }
  25. catch(InterruptedExceptione)
  26. {
  27. e.printStackTrace();
  28. }
  29. while(getQueueSize(tpe.getQueue())>=queueDeep)
  30. {
  31. System.out.println("隊列已滿,等3秒再添加任務");
  32. try
  33. {
  34. Thread.sleep(3000);
  35. }
  36. catch(InterruptedExceptione)
  37. {
  38. e.printStackTrace();
  39. }
  40. }
  41. TaskThreadPool ttp=newTaskThreadPool(i);
  42. System.out.println("put i:"+i);
  43. tpe.execute(ttp);
  44. }
  45. tpe.shutdown();
  46. }
  47. privatesynchronizedintgetQueueSize(Queuequeue)
  48. {
  49. returnqueue.size();
  50. }
  51. publicstaticvoidmain(String[]args)
  52. {
  53. ThreadPoolExecutorTest test=newThreadPoolExecutorTest();
  54. test.createThreadPool();
  55. }
  56. classTaskThreadPoolimplementsRunnable
  57. {
  58. privateintindex;
  59. publicTaskThreadPool(intindex)
  60. {
  61. this.index=index;
  62. }
  63. publicvoidrun()
  64. {
  65. System.out.println(Thread.currentThread()+" index:"+index);
  66. try
  67. {
  68. Thread.sleep(3000);
  69. }
  70. catch(InterruptedExceptione)
  71. {
  72. e.printStackTrace();
  73. }
  74. }
  75. }
  76. }

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 西乌珠穆沁旗| 高台县| 永新县| 辉县市| 沈丘县| 仙桃市| 南陵县| 运城市| 毕节市| 车险| 福州市| 洛扎县| 盐山县| 六安市| 修武县| 北海市| 德令哈市| 阜平县| 三都| 哈尔滨市| 龙南县| 扎赉特旗| 桐柏县| 铜山县| 渭南市| 廊坊市| 雷波县| 西峡县| 阳信县| 常山县| 台东县| 井陉县| 沭阳县| 巴中市| 南丰县| 读书| 绿春县| 海盐县| 甘肃省| 澄迈县| 通州区|