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

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

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Java教程 - Java ExecutorService四種線程池使用詳解

Java ExecutorService四種線程池使用詳解

2021-04-04 14:26木子道_ Java教程

這篇文章主要介紹了Java ExecutorService四種線程池使用詳解,小編覺得挺不錯的,現在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧

1.引言

合理利用線程池能夠帶來三個好處。第一:降低資源消耗。通過重復利用已創建的線程降低線程創建和銷毀造成的消耗。第二:提高響應速度。當任務到達時,任務可以不需要的等到線程創建就能立即執行。第三:提高線程的可管理性。線程是稀缺資源,如果無限制的創建,不僅會消耗系統資源,還會降低系統的穩定性,使用線程池可以進行統一的分配,調優和監控。但是要做到合理的利用線程池,必須對其原理了如指掌。

2.線程池使用

Executors提供的四種線程 1.newCachedThreadPool創建一個可緩存線程池,如果線程池長度超過處理需要,可靈活回收空閑線程,若無可回收,則新建線程。 2.newFixedThreadPool 創建一個定長線程池,可控制線程最大并發數,超出的線程會在隊列中等待。 3.newScheduledThreadPool 創建一個定長線程池,支持定時及周期性任務執行。 4.newSingleThreadExecutor 創建一個單線程化的線程池,它只會用唯一的工作線程來執行任務,保證所有任務按照指定順序(FIFO, LIFO, 優先級)執行。

1.newCachedThreadPool創建一個可緩存線程池,如果線程池長度超過處理需要,可靈活回收空閑線程,若無可回收,則新建線程。示例如下

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
ExecutorService executorService = Executors.newCachedThreadPool();
for(int i=0;i<5;i++){
  final int index = i;
  try {
    Thread.sleep(index * 1000);
  } catch (InterruptedException e) {
    e.printStackTrace();
  }
  executorService.execute(new Runnable() {
    @Override
    public void run() {
      System.out.println(Thread.currentThread().getName() + "," +index);
    }
  });
}
//控制臺信息
pool-1-thread-1,0
pool-1-thread-1,1
pool-1-thread-1,2
pool-1-thread-1,3
pool-1-thread-1,4

2.newFixedThreadPool創建一個定長線程池,可控制線程最大并發數,超出的線程會在隊列中等待。示例如下

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
ExecutorService fixedThreadPool = Executors.newFixedThreadPool(4);
for(int i=0;i<5;i++) {
  final int index = i;
    fixedThreadPool.execute(new Runnable() {
    @Override
    public void run() {
      try {
        System.out.println(Thread.currentThread().getName() + ", " + index);
        Thread.sleep(2000);
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
    }
  });
}
//控制臺信息
pool-1-thread-1,0
pool-1-thread-2,1
pool-1-thread-3,2
pool-1-thread-4,3
pool-1-thread-1,4

3.newScheduledThreadPool 創建一個定長線程池,支持周期和定時任務示例如下

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(5);
System.out.println("before:" + System.currentTimeMillis()/1000);
scheduledThreadPool.schedule(new Runnable() {
  @Override
  public void run() {
    System.out.println("延遲3秒執行的哦 :" + System.currentTimeMillis()/1000);
  }
}, 3, TimeUnit.SECONDS);
System.out.println("after :" +System.currentTimeMillis()/1000);
//控制臺信息
before:1518012703
after :1518012703
延遲3秒執行的哦 :1518012706
System.out.println("before:" + System.currentTimeMillis()/1000);
scheduledThreadPool.scheduleAtFixedRate(new Runnable() {
  @Override
  public void run() {
    System.out.println("延遲1秒之后,3秒執行一次:" +System.currentTimeMillis()/1000);
  }
}, 1, 3, TimeUnit.SECONDS);
System.out.println("after :" +System.currentTimeMillis()/1000);

控制臺消息
before:1518013024
after :1518013024
延遲1秒之后,3秒執行一次:1518013025
延遲1秒之后,3秒執行一次:1518013028
延遲1秒之后,3秒執行一次:1518013031

4.newSingleThreadExecutor創建一個單線程化的線程池,只會用工作線程來執行任務,保證順序,示例如下

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();
for (int i=0;i<10;i++) {
  final int index = i;
  singleThreadExecutor.execute(new Runnable() {
    @Override
    public void run() {
      try {
         System.out.println(Thread.currentThread().getName() + "," + index);
        Thread.sleep(2000);
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
    }
  });
}

控制臺信息
pool-1-thread-1,0
pool-1-thread-1,1
pool-1-thread-1,2
pool-1-thread-1,3
pool-1-thread-1,4

向線程池提交任務 ThreadPoolExecutor類中execute()和submit()區別 execute()方法實際上是Executor中聲明的方法,在ThreadPoolExecutor進行了具體的實現,這個方法是ThreadPoolExecutor的核心方法,通過這個方法可以向線程池提交一個任務,交由線程池去執行。

submit()方法是在ExecutorService中聲明的方法,在AbstractExecutorService就已經有了具體的實現,在ThreadPoolExecutor中并沒有對其進行重寫,這個方法也是用來向線程池提交任務的,但是它和execute()方法不同,它能夠返回任務執行的結果,通過源碼查看submit()方法的實現,會發現它實際上還是調用的execute()方法,只不過它利用了Future來獲取任務執行結果。

?
1
2
3
4
5
6
7
8
9
10
/**
 * @throws RejectedExecutionException {@inheritDoc}
 * @throws NullPointerException    {@inheritDoc}
 */
public Future<?> submit(Runnable task) {
  if (task == null) throw new NullPointerException();
  RunnableFuture<Void> ftask = newTaskFor(task, null);
  execute(ftask);
  return ftask;
}

線程池的關閉 我們可以通過調用線程池的shutdown或shutdownNow方法來關閉線程池,但是它們的實現原理不同,shutdown的原理是只是將線程池的狀態設置成SHUTDOWN狀態,然后中斷所有沒有正在執行任務的線程。shutdownNow的原理是遍歷線程池中的工作線程,然后逐個調用線程的interrupt方法來中斷線程,所以無法響應中斷的任務可能永遠無法終止。shutdownNow會首先將線程池的狀態設置成STOP,然后嘗試停止所有的正在執行或暫停任務的線程,并返回等待執行任務的列表。

只要調用了這兩個關閉方法的其中一個,isShutdown方法就會返回true。當所有的任務都已關閉后,才表示線程池關閉成功,這時調用isTerminaed方法會返回true。至于我們應該調用哪一種方法來關閉線程池,應該由提交到線程池的任務特性決定,通常調用shutdown來關閉線程池,如果任務不一定要執行完,則可以調用shutdownNow。

3.  線程池的分析

流程分析:線程池的主要工作流程如下圖: Java線程池主要工作流程

Java ExecutorService四種線程池使用詳解

從上圖我們可以看出,當提交一個新任務到線程池時,線程池的處理流程如下:

  1. 首先線程池判斷基本線程池是否已滿?沒滿,創建一個工作線程來執行任務。滿了,則進入下個流程。
  2. 其次線程池判斷工作隊列是否已滿?沒滿,則將新提交的任務存儲在工作隊列里。滿了,則進入下個流程。
  3. 最后線程池判斷整個線程池是否已滿?沒滿,則創建一個新的工作線程來執行任務,滿了,則交給飽和策略來處理這個任務。

**源碼分析。**上面的流程分析讓我們很直觀的了解的線程池的工作原理,讓我們再通過源代碼來看看是如何實現的。線程池執行任務的方法如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public void execute(Runnable command) {
  if (command == null)
    throw new NullPointerException();
  int c = ctl.get();
  if (workerCountOf(c) < corePoolSize) {
    if (addWorker(command, true))
      return;
    c = ctl.get();
  }
  if (isRunning(c) && workQueue.offer(command)) {
    int recheck = ctl.get();
    if (! isRunning(recheck) && remove(command))
      reject(command);
    else if (workerCountOf(recheck) == 0)
      addWorker(null, false);
  }
  else if (!addWorker(command, false))
    reject(command);
}

工作線程。線程池創建線程時,會將線程封裝成工作線程Worker,Worker在執行完任務后,還會無限循環獲取工作隊列里的任務來執行。

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

原文鏈接:https://my.oschina.net/u/3758413/blog/1620433

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 色哟约| 美女gif趴跪式抽搐动态图 | 午夜宅男网 | 亚洲品质水蜜桃 | 国产精品久久现线拍久青草 | 2020国产精品视频免费 | 国产成人a∨麻豆精品 | 艾秋麻豆果冻传媒老狼仙踪林 | 亚洲第一色视频 | 丝袜足液精子免费视频 | 亚洲视频在线一区二区三区 | 久久www免费人成高清 | 午夜深情在线观看免费 | 久久精品国产色蜜蜜麻豆国语版 | 国产成人精品男人的天堂538 | 精品久久日日躁夜夜躁AV | 日本精品一区二区在线播放 | 日韩精品成人a在线观看 | 男人天堂bt| 国产欧美视频一区二区三区 | 男人天堂bt | 热巴在公交车h文 | 天天做天天爱天天爽综合网 | 91极品女神久色在线播放 | 国产福利一区二区三区 | 精品亚洲视频在线观看 | 久久这里只有精品国产精品99 | 校园高h| 夫妇交换小说全文阅读 | www.日日爱 | 亚洲国产视频网站 | 三上悠亚精品专区久久 | 日本福利视频一区 | xxxxxx日本处大片免费看 | 操老肥熟| 午夜影院c绿象 | 欧美日韩一区二区综合 | 翁熄性放纵交换01 | 久久综合给合久久狠狠狠… | 手机看片日韩1024你懂的首页 | 亚洲人成综合在线播放 |