一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|JAVA教程|ASP教程|編程技術|正則表達式|

服務器之家 - 編程語言 - JAVA教程 - java ExecutorService使用方法詳解

java ExecutorService使用方法詳解

2020-07-09 10:39tengdazhang770960436 JAVA教程

這篇文章主要為大家詳細介紹了java ExecutorService使用方法,具有一定的參考價值,感興趣的小伙伴們可以參考一下

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

例子:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
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());
 }
}
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
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值,這個線程在下次循環的時候就會自動退出了。

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持服務器之家。

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 色中色破解版 | 精品一区二区视频 | 亚州中文字幕 | 日本视频免费在线 | 日韩在线1 | 高清黄色直接看 | 美女撒尿无遮挡免费中国 | 91久久国产成人免费观看资源 | 2020韩国三级理论在线观看 | 国产成人高清精品免费5388密 | 千金奴隶在线 | 久久久久青草大香线综合精品 | 99国产精品热久久久久久夜夜嗨 | 美女扒开腿让男生捅 | 免费人成在线观看69式小视频 | 99久视频 | 亚洲视频男人的天堂 | a国产在线| gogo人体模特啪啪季玥图片 | 青青青国产在线 | 国产自精品| 亚洲精品丝袜在线一区波多野结衣 | 国产一卡二卡3卡4卡四卡在线视频 | 色婷婷影院在线视频免费播放 | 四虎麻豆国产精品 | 国产日韩高清一区二区三区 | 人与动人物人a级特片 | boobsmilking流奶水 | 九九在线免费视频 | 黑人艹| 亚洲第一区欧美日韩精品 | 羞羞污视频 | 91超级碰| 欧美极品摘花过程 | 97超pen个人视频公开视频视 | 亚洲丁香网 | 99热精品在线免费观看 | 操小女人 | 无颜之月全集免费观看 | 久久精品国产视频澳门 | 国产特级 |