并發編程-concurrent指南-線程池ExecutorService的使用

有幾種不同的方式來將任務委托給 ExecutorService 去執行:

  • execute(Runnable)
  • submit(Runnable)
  • submit(Callable)
  • invokeAny(…)
  • invokeAll(…)

execute(Runnable)

execute(Runnable) 方法要求一個 java.lang.Runnable 對象,然后對它進行異步執行。以下是使用 ExecutorService 執行一個 Runnable 的示例:

ExecutorService executorService = Executors.newSingleThreadExecutor();  executorService.execute(new Runnable() {  public void run() {  System.out.println("Asynchronous task");  }  
});  executorService.shutdown(); 

沒有辦法得知被執行的 Runnable 的執行結果。如果有需要的話你得使用一個 Callable(以下將做介紹)。

?

submit(Runnable)

submit(Runnable) 方法也要求一個 Runnable 實現類,但它返回一個 Future 對象。這個 Future 對象可以用來檢查 Runnable 是否已經執行完畢。

以下是 ExecutorService submit() 示例:

Future future = executorService.submit(new Runnable() {  public void run() {  System.out.println("Asynchronous task");  }  
});  future.get();  //returns null if the task has finished correctly.  

?

submit(Callable)

submit(Callable) 方法類似于 submit(Runnable) 方法,除了它所要求的參數類型之外。Callable 實例除了它的 call() 方法能夠返回一個結果之外和一個 Runnable 很相像。Runnable.run() 不能夠返回一個結果。
Callable 的結果可以通過 submit(Callable) 方法返回的 Future 對象進行獲取。以下是一個 ExecutorService Callable 示例:

import java.util.concurrent.*;public class Main {public static void main(String[] args) {ExecutorService executorService = Executors.newSingleThreadExecutor();Future future = executorService.submit(new Runnable() {public void run() {try {TimeUnit.SECONDS.sleep(4);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("Asynchronous task");}});System.out.println("主方法。。。。");try {System.out.println(future.get());  //returns null if the task has finished correctly.} catch (InterruptedException e) {e.printStackTrace();} catch (ExecutionException e) {e.printStackTrace();}}
}

結果:

主方法。。。。
Asynchronous task
null

future.get()會等待子線程結束后,打印出信息。

submit(Callable)

submit(Callable) 方法類似于 submit(Runnable) 方法,除了它所要求的參數類型之外。Callable 實例除了它的 call() 方法能夠返回一個結果之外和一個 Runnable 很相像。Runnable.run() 不能夠返回一個結果。
Callable 的結果可以通過 submit(Callable) 方法返回的 Future 對象進行獲取。以下是一個 ExecutorService Callable 示例:

import java.util.concurrent.*;public class Main {public static void main(String[] args) {ExecutorService executorService = Executors.newSingleThreadExecutor();Future future = executorService.submit(new Callable(){public Object call() throws Exception {TimeUnit.SECONDS.sleep(3);System.out.println("Asynchronous Callable");return "Callable Result";}});System.out.println("主方法。。。。");try {System.out.println(future.get());  //returns null if the task has finished correctly.} catch (InterruptedException e) {e.printStackTrace();} catch (ExecutionException e) {e.printStackTrace();}}
}

結果:

主方法。。。。
Asynchronous Callable
Callable Result

future.get()會等待子線程結束后,打印出信息


invokeAll()

invokeAll() 方法將調用你在集合中傳給 ExecutorService 的所有 Callable 對象。invokeAll() 返回一系列的 Future 對象,通過它們你可以獲取每個 Callable 的執行結果。

記住,一個任務可能會由于一個異常而結束,因此它可能沒有 “成功”。無法通過一個 Future 對象來告知我們是兩種結束中的哪一種。

以下是一個代碼示例:

import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.*;public class Main {public static void main(String[] args) {ExecutorService executorService = Executors.newSingleThreadExecutor();Set<Callable<String>> callables = new HashSet<Callable<String>>();callables.add(new Callable<String>() {public String call() throws Exception {System.out.println(Thread.currentThread().getName()+",Task 1");return "Task 1";}});callables.add(new Callable<String>() {public String call() throws Exception {System.out.println(Thread.currentThread().getName()+",Task 2");return "Task 2";}});callables.add(new Callable<String>() {public String call() throws Exception {System.out.println(Thread.currentThread().getName()+",Task 3");return "Task 3";}});callables.add(new Callable<String>() {public String call() throws Exception {System.out.println(Thread.currentThread().getName()+",Task 4");return "Task 4";}});callables.add(new Callable<String>() {public String call() throws Exception {System.out.println(Thread.currentThread().getName()+",Task 5");return "Task 5";}});try {List<Future<String>> futures  = executorService.invokeAll(callables);for(Future<String> future : futures){System.out.println("future.get = " + future.get());}} catch (InterruptedException e) {e.printStackTrace();} catch (ExecutionException e) {e.printStackTrace();}executorService.shutdown();}
}

?

結果:

pool-1-thread-1,Task 2
pool-1-thread-1,Task 5
pool-1-thread-1,Task 4
pool-1-thread-1,Task 1
pool-1-thread-1,Task 3
future.get = Task 2
future.get = Task 5
future.get = Task 4
future.get = Task 1
future.get = Task 3

?

ExecutorService 關閉

使用完 ExecutorService 之后你應該將其關閉,以使其中的線程不再運行。

比如,如果你的應用是通過一個 main() 方法啟動的,之后 main 方法退出了你的應用,如果你的應用有一個活動的 ExexutorService 它將還會保持運行。ExecutorService 里的活動線程阻止了 JVM 的關閉。

要終止 ExecutorService 里的線程你需要調用 ExecutorService 的 shutdown() 方法。ExecutorService 并不會立即關閉,但它將不再接受新的任務,而且一旦所有線程都完成了當前任務的時候,ExecutorService 將會關閉。在 shutdown() 被調用之前所有提交給 ExecutorService 的任務都被執行

如果你想要立即關閉 ExecutorService,你可以調用 shutdownNow() 方法。這樣會立即嘗試停止所有執行中的任務,并忽略掉那些已提交但尚未開始處理的任務。無法擔保執行任務的正確執行。可能它們被停止了,也可能已經執行結束。

?




?

轉載于:https://www.cnblogs.com/qjm201000/p/10156491.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/450303.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/450303.shtml
英文地址,請注明出處:http://en.pswp.cn/news/450303.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

怎樣去理解@ComponentScan注解

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 怎么樣去理解它呢&#xff1f; 1.配置視圖控制器 [java] view plain copy package com.apress.prospringmvc.bookstore.web.config; imp…

oracle 如何創建序列squence

create sequence 序列名 start with 1 increment by 1 nomaxvalue nominvalue nocycle nocache;

如何高效、可移植申請內存代碼。

在視頻編解碼中&#xff0c;如何申請char mem_2D[1920][1080], char mem_3D[4][1920][1080], char mem_4D[6][4][1920][1080]&#xff0c;高效 又 可移植申請內存呢&#xff1f; 請看如下代碼&#xff1a; 看完后&#xff0c;如要申請的是 int &#xff0c;不是cha…

CSS中的px與物理像素、邏輯像素、1px邊框問題

一直不太清楚CSS中的1px與邏輯像素、物理像素是個什么關系&#xff08;作為一名前端感覺很慚愧 -_-&#xff01;&#xff09;&#xff0c;今天終于花時間徹底弄清楚了&#xff0c;其實弄清楚之后就覺得事情很簡單&#xff0c;但也只有在弄清楚之后&#xff0c;才會覺得簡單&…

平滑數據遷移,不影響服務

為什么80%的碼農都做不了架構師&#xff1f;>>> 轉自&#xff1a;http://www.10tiao.com/html/249/201703/2651959992/1.html 轉載于:https://my.oschina.net/jzgycq/blog/2872104

spring cache相關注解介紹 @Cacheable、@CachePut、@CacheEvict

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 Cacheable是用來聲明方法是可緩存的。將結果存儲到緩存中以便后續使用相同參數調用時不需執行實際的方法。直接從緩存中取值。最簡單的格…

layui 渲染select下拉選項 ,日期控件的用法

最近項目中用到關于layui的前端技術&#xff0c;在使用layui 渲染select option下拉復選框時出現了沒有值渲染的問題&#xff0c;還有使用layui日期的過程 &#xff0c;接下來就一起看看吧。 /** *從后臺渲染字段民族數據/<div class"layui-inline"><labe…

CF1082G Petya and Graph(最小割,最大權閉合子圖)

QWQ嚶嚶嚶 感覺是最水的一道\(G\)題了 順便記錄一下第一次在考場上做出來G qwqqq 題目大意就是說&#xff1a; 給你n個點&#xff0c;m條邊&#xff0c;讓你選出來一些邊&#xff0c;最大化邊權減點權 \(n\le 1000\) QWQ 看完這個題和數據范圍&#xff0c;第一感覺就是網絡流啊…

NET Core微服務之路:讓我們對上一個Demo通訊進行修改,完成RPC通訊

最近一段時間有些事情耽擱了更新&#xff0c;抱歉各位了。上一篇我們簡單的介紹了DotNetty通信框架&#xff0c;并簡單的介紹了基于DotNetty實現了回路&#xff08;Echo&#xff09;通信過程。我們來回憶一下上一個項目的整個流程&#xff1a;當服務端啟動后&#xff0c;綁定并…

Centos7防火墻設置

查看防火墻狀態 or rootlocalhost ~]# systemctl status firewalld / firewall-cmd --state 啟動防火墻 [rootlocalhost ~]# systemctl start firewalld 關閉防火墻 [rootlocalhost ~]# systemctl stop firewalld 設置開機啟動 [rootlocalhost ~]# systemctl enable fi…

HTTP協議中POST、GET、HEAD、PUT等請求方法及相應值得含義

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 請求方法是請求一定的Web頁面的程序或用于特定的URL。可選用下列幾種&#xff1a; GET&#xff1a; 請求指定的頁面信息&#xff0c;并…

java面試題文檔(QA)

– 基礎篇 1、 Java語言有哪些特點2、面向對象和面向過程的區別3 、八種基本數據類型的大小&#xff0c;以及他們的封裝類4、標識符的命名規則。5、instanceof 關鍵字的作用6、Java自動裝箱與拆箱7、 重載和重寫的區別8、 equals與的區別9、 Hashcode的作用10、String、String …

第四次軟件工程作業

關于 石墨文檔客戶端 的案例分析 作業地址&#xff1a; https://edu.cnblogs.com/campus/nenu/2016CS/homework/2505 第一部分 調研&#xff0c; 評測 1.下載并使用&#xff0c;按照描述的bug定義&#xff0c;找3~5個功能性的比較嚴重的bug。請用專業的語言描述&#xff08;每個…

深入剖析C++中的string類

一&#xff0c;C語言的字符串 在C語言里&#xff0c;對字符串的處理一項都是一件比較痛苦的事情&#xff0c;因為通常在實現字符串的操作的時候都會用到最不容易駕馭的類型——指針。 比如下面這個例子&#xff1a; //example 1: char str[12] "Hello"; char *…

Apple System: Error: ENFILE: file table overflow

2019獨角獸企業重金招聘Python工程師標準>>> 在MAC上跑nodejs&#xff0c;遇到了一個問題&#xff1a;file table overflow 主要意思就是說文件打開太多了&#xff0c;超過了限制&#xff0c;產生這個問題主要是蘋果操作系統的限制。 echo kern.maxfiles65536 | sud…

springboot的緩存技術

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 我門知道一個程序的瓶頸在于數據庫&#xff0c;我門也知道內存的速度是大大快于硬盤的速度的。當我門需要重復的獲取相同的數據的時候&a…

深度優先遍歷解決連通域求解問題-python實現

問題描述 在一個矩形網格中每一個格子的顏色或者為白色或者為黑色。任意或上、或下、或左、或右相鄰同為黑色的格子組成一個家族。家族中所有格子的數量反映家族的大小。要求找出最大家族的家族大小&#xff08;組成最大家族的格子的數量&#xff09;并統計出哪些點屬于哪一族。…

字符串進階

C風格字符串 1、字符串是用字符型數組存儲的&#xff0c;字符串要求其尾部以’\0’作為結束標志。如&#xff1a; char string[ ]”C programming language”; 用sizeof來測string長度為25個字節&#xff0c;而實際串本身長度(含空格)為24個字節&#xff0c;多出來的一個就是…

flask上傳excel文件,無須存儲,直接讀取內容

運行環境python3.6 import xlrd from flask import Flask, requestapp Flask(__name__)app.route("/", methods[POST, GET]) def filelist1():print(request.files)file request.files[file]print(file, type(file), file)print(file.filename) # 打印文件名f …

分布式 ID的 9 種生成方式

一、為什么要用分布式 ID&#xff1f; 在說分布式 ID 的具體實現之前&#xff0c;我們來簡單分析一下為什么用分布式 ID&#xff1f;分布式 ID 應該滿足哪些特征&#xff1f; 1、什么是分布式 ID&#xff1f; 拿 MySQL 數據庫舉個栗子&#xff1a; 在我們業務數據量不大的時…