java ExecutorService使用方法詳解_java

來源:互聯網
上載者:User

下面的例子主要討論兩個問題:
問題1.線程池固定大小,假設為5.那麼向線程池放入10個線程,運行效果如何?其他線程的狀態?
問題2.那麼如何從線程池中移除某一個線程,確切說是使某一個線程成為空白閑線程?

例子:

package com.dada.executorService;  import java.util.concurrent.TimeUnit;  public class JobThread extends Thread {    // 為線程命名  public JobThread(String name,long threadId) {   super(name);  }    @Override  public void run() {   // 如果主線程包含這個線程就一直運行   while (MainThread.threadNameMap.containsKey(this.getName())) {    try {     System.out.println("線程名稱:-----" + this.getName());     TimeUnit.SECONDS.sleep(4);    } catch (Exception e) {     e.printStackTrace();    }   }   System.out.println("***************線程結束,線程名稱:*********" + this.getName());  } } 
package com.dada.executorService;  import java.util.HashMap; import java.util.Map; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit;  public class MainThread {  public static final int THREADPOOL_SIZE = 5;  // 產生固定大小的線程池  public static ExecutorService exec = Executors.newFixedThreadPool(THREADPOOL_SIZE);  // 用來儲存線程名稱的map  public static Map<String, String> threadNameMap = new HashMap<String, String>();    public static void main(String[] args) {   // 向線程池中插入 10 個線程,但是線程池只允許最大 5 個線程,所以其他 5 個線程等待中   for (int i = 0; i < THREADPOOL_SIZE + 5; i++) {    String threadName = getThreadName(i);    threadNameMap.put(threadName, threadName);    exec.execute(new JobThread(threadName, i));   }      System.out.println("Hash表的Size:" + threadNameMap.size());      try {    System.out.println("主線程睡一會!");    TimeUnit.SECONDS.sleep(3);   } catch (Exception e) {    e.printStackTrace();    System.out.println("醒了!");   }        // 下面的這幾個用來刪除線程池裡面的線程   //removeThread(0);   //removeThread(1);   //removeThread(2);  }    public static void removeThread(int i) {   threadNameMap.remove(getThreadName(i));   System.out.println("刪除線程Thread" + i + ", Hash表的Size:" + threadNameMap.size());  }    public static String getThreadName(int i) {   return "threadname"+i;  }   } 

直接運行代碼結果:

線程名稱:-----threadname0
Hash表的Size:10
主線程睡一會!
線程名稱:-----threadname2
線程名稱:-----threadname4
線程名稱:-----threadname1
線程名稱:-----threadname3
線程名稱:-----threadname4
線程名稱:-----threadname2
線程名稱:-----threadname3
線程名稱:-----threadname1
線程名稱:-----threadname0
線程名稱:-----threadname1
線程名稱:-----threadname3
線程名稱:-----threadname0
線程名稱:-----threadname4
線程名稱:-----threadname2
線程名稱:-----threadname1
線程名稱:-----threadname3
線程名稱:-----threadname4

結論:
發現列印的:線程名稱一直從threadname0到threadname4,沒有其他的名稱。
由此證明:向線程池中放入10個線程,但是線程池的大小為5,只能給5個線程分配CPU,啟動並執行就是最先放入線程池中的5個線程,其他線程都處於就緒狀態(阻塞狀態)。

去掉注釋之後代碼運行結果:

線程名稱:-----threadname0
線程名稱:-----threadname2
線程名稱:-----threadname4
Hash表的Size:10
主線程睡一會!
線程名稱:-----threadname1
線程名稱:-----threadname3
刪除線程Thread0, Hash表的Size:9
刪除線程Thread1, Hash表的Size:8
刪除線程Thread2, Hash表的Size:7
***************線程結束,線程名稱:*********threadname2
***************線程結束,線程名稱:*********threadname0
線程名稱:-----threadname5
線程名稱:-----threadname6
***************線程結束,線程名稱:*********threadname1
線程名稱:-----threadname4
線程名稱:-----threadname7
線程名稱:-----threadname3
線程名稱:-----threadname6
線程名稱:-----threadname5
線程名稱:-----threadname7
線程名稱:-----threadname4
線程名稱:-----threadname3
線程名稱:-----threadname5
線程名稱:-----threadname6
線程名稱:-----threadname7
線程名稱:-----threadname4
線程名稱:-----threadname3

結論:
從結果中可以看出,在移除線程之前,啟動並執行線程還是從thread0到thread4。當移除線程thread0後,新的線程thread3開始運行,而且是按照順序到threadname7。

總結如下:

1.線程池固定大小,假設為5.那麼向線程池放入10個線程,運行效果如何?其他線程的狀態?
a.線程池的概念就是你不斷的向其中push請求,但是它只能處理規定額度的線程,多餘的線程都會在其中等待。
b.當其中一個線程處理完畢(業務執行完畢或退出while迴圈),線程池就會自動從等待的隊列中取出一個作業,使用閒置線程來運行這個作業。運行線程池中的哪個,從例子上來看應該是按照被放入的先後順序來的。 

2.那麼如何從線程池中移除某一個線程,確切說是使某一個線程成為空白閑線程?
線程池無法擷取其中某一個線程並殺掉他,因為使用線程池的主線程和主線程開啟的線程是平級的,誰都無權主宰另一方的存亡。但是可以換一個方式,委婉的達到目的。
a.主線程維護一個Hash表可以是一個HashMap。key值任意,但是要唯一,可以唯一標示一個線程。
b.所有放入線程池的線程,都要產生一個key值,然後存入這個HashMap中。
c.對於迴圈類的線程,如while(true)的線程。需要增加一個條件,每一輪迴圈校正這個線程的key是否存在於上面HashMap中。如果不存在則退出while迴圈。
d.雖然主線程不可以主宰其他線程的存亡,但是可以對自己的HashMap進行put或是remove操作。到此,只要從HashMap中移除線程對應的Key值,這個線程在下次迴圈的時候就會自動結束了。

以上就是本文的全部內容,希望對大家的學習有所協助,也希望大家多多支援雲棲社區。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.