日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

java Concurrent包学习笔记(一):ExecutorService

發(fā)布時(shí)間:2024/1/17 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java Concurrent包学习笔记(一):ExecutorService 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

一、介紹

ExecutorService是java.util.concurrent包中的一個(gè)線程池實(shí)現(xiàn)接口。其有兩個(gè)實(shí)現(xiàn)類:

? 1)ThreadPoolExecutor:普通線程池通過配置線程池大小,能有效管理線程的調(diào)度,在執(zhí)行大量異步線程時(shí)提高程序的性能。

/*** Creates a new {@code ThreadPoolExecutor} with the given initial* parameters.** @param corePoolSize the number of threads to keep in the pool, even* if they are idle, unless {@code allowCoreThreadTimeOut} is set* @param maximumPoolSize the maximum number of threads to allow in the* pool* @param keepAliveTime when the number of threads is greater than* the core, this is the maximum time that excess idle threads* will wait for new tasks before terminating.* @param unit the time unit for the {@code keepAliveTime} argument* @param workQueue the queue to use for holding tasks before they are* executed. This queue will hold only the {@code Runnable}* tasks submitted by the {@code execute} method.* @param threadFactory the factory to use when the executor* creates a new thread* @param handler the handler to use when execution is blocked* because the thread bounds and queue capacities are reached* @throws IllegalArgumentException if one of the following holds:<br>* {@code corePoolSize < 0}<br>* {@code keepAliveTime < 0}<br>* {@code maximumPoolSize <= 0}<br>* {@code maximumPoolSize < corePoolSize}* @throws NullPointerException if {@code workQueue}* or {@code threadFactory} or {@code handler} is null*/public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,BlockingQueue<Runnable> workQueue,ThreadFactory threadFactory,RejectedExecutionHandler handler) {if (corePoolSize < 0 ||maximumPoolSize <= 0 ||maximumPoolSize < corePoolSize ||keepAliveTime < 0)throw new IllegalArgumentException();if (workQueue == null || threadFactory == null || handler == null)throw new NullPointerException();this.corePoolSize = corePoolSize;this.maximumPoolSize = maximumPoolSize;this.workQueue = workQueue;this.keepAliveTime = unit.toNanos(keepAliveTime);this.threadFactory = threadFactory;this.handler = handler;}
  • corePoolSize:核心線程數(shù),如果運(yùn)行的線程少于corePoolSize,則創(chuàng)建新線程來執(zhí)行新任務(wù),即使線程池中的其他線程是空閑的
  • maximumPoolSize:最大線程數(shù),可允許創(chuàng)建的線程數(shù),corePoolSize和maximumPoolSize設(shè)置的邊界自動(dòng)調(diào)整池大小:?
  • corePoolSize <運(yùn)行的線程數(shù)< maximumPoolSize:僅當(dāng)隊(duì)列滿時(shí)才創(chuàng)建新線程
  • corePoolSize=運(yùn)行的線程數(shù)= maximumPoolSize:創(chuàng)建固定大小的線程池
  • keepAliveTime:如果線程數(shù)多于corePoolSize,則這些多余的線程的空閑時(shí)間超過keepAliveTime時(shí)將被終止
  • unit:keepAliveTime參數(shù)的時(shí)間單位
  • workQueue:保存任務(wù)的阻塞隊(duì)列,與線程池的大小有關(guān):?
  • 當(dāng)運(yùn)行的線程數(shù)少于corePoolSize時(shí),在有新任務(wù)時(shí)直接創(chuàng)建新線程來執(zhí)行任務(wù)而無需再進(jìn)隊(duì)列?
  • 當(dāng)運(yùn)行的線程數(shù)等于或多于corePoolSize,在有新任務(wù)添加時(shí)則選加入隊(duì)列,不直接創(chuàng)建線程?
  • 當(dāng)隊(duì)列滿時(shí),在有新任務(wù)時(shí)就創(chuàng)建新線程
  • threadFactory:使用ThreadFactory創(chuàng)建新線程,默認(rèn)使用defaultThreadFactory創(chuàng)建線程
  • handle:定義處理被拒絕任務(wù)的策略,默認(rèn)使用ThreadPoolExecutor.AbortPolicy,任務(wù)被拒絕時(shí)將拋出RejectExecutorException

?

? 2)ScheduledThreadPoolExecutor:執(zhí)行延遲任務(wù)和周期性任務(wù)。

二、ExecutorService種類

?1、newSingleThreadExecutor

由數(shù)可知,創(chuàng)建一個(gè)單線程化的線程池,它只會(huì)用唯一的工作線程來執(zhí)行任務(wù),沒有被執(zhí)行的線程先排在等待隊(duì)列中,而且先放入線程池的先執(zhí)行

?示例:

package executorservice.demo; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors;/*** @author boshen* @date 2018/12/20*/ public class SingleThreadExecutorTest {class StudentThread implements Runnable{private String name;StudentThread(String name){this.name = name;}public void run(){System.out.println("學(xué)生:" + name + " 開始吃飯");try {Thread.sleep(3000);System.out.println("學(xué)生:" + name + " 吃完飯了");} catch (InterruptedException e) {e.printStackTrace();}}}public static void main(String[] args){SingleThreadExecutorTest cb = new SingleThreadExecutorTest();ExecutorService executorService = Executors.newSingleThreadExecutor();executorService.submit(cb.new StudentThread("張三"));executorService.submit(cb.new StudentThread("李四"));executorService.shutdown();} } 學(xué)生:張三 開始吃飯 學(xué)生:張三 吃完飯了 學(xué)生:李四 開始吃飯 學(xué)生:李四 吃完飯了

?2、newFixedThreadPool

??

?創(chuàng)建一個(gè)定長(zhǎng)線程池,可控制線程最大并發(fā)數(shù),超出的線程會(huì)在隊(duì)列中等待

?示例:

package executorservice.demo; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors;/*** @author boshen* @date 2018/12/20*/ public class FixedThreadPoolTest {class StudentThread implements Runnable{private String name;StudentThread(String name){this.name = name;}public void run(){System.out.println("學(xué)生:" + name + " 開始吃飯");try {Thread.sleep(2000);System.out.println("學(xué)生:" + name + " 吃完飯了");} catch (InterruptedException e) {e.printStackTrace();}}}public static void main(String[] args){FixedThreadPoolTest cb = new FixedThreadPoolTest(); ExecutorService executorService = Executors.newFixedThreadPool(2);executorService.submit(cb.new StudentThread("張三"));executorService.submit(cb.new StudentThread("李四"));executorService.submit(cb.new StudentThread("王五"));executorService.submit(cb.new StudentThread("馬六"));executorService.shutdown();} } 學(xué)生:李四 開始吃飯 學(xué)生:張三 開始吃飯 學(xué)生:李四 吃完飯了 學(xué)生:張三 吃完飯了 學(xué)生:王五 開始吃飯 學(xué)生:馬六 開始吃飯 學(xué)生:馬六 吃完飯了 學(xué)生:王五 吃完飯了

?

?3、newCachedThreadPool

創(chuàng)建可緩存的線程池,如果線程池中的線程在60秒未被使用就將被移除,在執(zhí)行新的任務(wù)時(shí),當(dāng)線程池中有之前創(chuàng)建的可用線程就重用可用線程,否則就新建一條線程

?示例:

package executorservice.demo; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors;/*** @author boshen* @date 2018/12/20*/ public class CachedThreadPoolTest {class StudentThread1 implements Runnable{private String name;StudentThread1(String name){this.name = name;}public void run(){System.out.println("學(xué)生:" + name + " 開始吃飯,線程名為:"+Thread.currentThread().getName());try {Thread.sleep(2000);} catch (InterruptedException e) {e.printStackTrace();}}}class StudentThread2 implements Runnable{private String name;StudentThread2(String name){this.name = name;}public void run(){System.out.println("學(xué)生:" + name + " 開始吃飯,線程名為:"+Thread.currentThread().getName());try {Thread.sleep(10000);} catch (InterruptedException e) {e.printStackTrace();}}}public static void main(String[] args){CachedThreadPoolTest cb = new CachedThreadPoolTest();ExecutorService executorService = Executors.newCachedThreadPool();executorService.submit(cb.new StudentThread1("張三"));executorService.submit(cb.new StudentThread1("李四"));executorService.submit(cb.new StudentThread2("王五"));executorService.submit(cb.new StudentThread2("馬六"));try {Thread.sleep(4000);} catch (InterruptedException e) {e.printStackTrace();}executorService.submit(cb.new StudentThread1("趙七"));executorService.submit(cb.new StudentThread1("楊八"));executorService.shutdown();} } 學(xué)生:張三 開始吃飯,線程名為:pool-1-thread-1 學(xué)生:王五 開始吃飯,線程名為:pool-1-thread-3 學(xué)生:馬六 開始吃飯,線程名為:pool-1-thread-4 學(xué)生:李四 開始吃飯,線程名為:pool-1-thread-2 學(xué)生:趙七 開始吃飯,線程名為:pool-1-thread-2 學(xué)生:楊八 開始吃飯,線程名為:pool-1-thread-1

由結(jié)果可知:

張三和李四執(zhí)行時(shí)間為2秒,王五和馬六執(zhí)行時(shí)間為10秒,提交了前4個(gè)線程之后隔了4秒提交趙七和楊八的線程,這時(shí)候張三和李四已經(jīng)執(zhí)行完了。

所以張三的線程pool-1-thread-1繼續(xù)執(zhí)行楊八,李四的線程pool-1-thread-2繼續(xù)執(zhí)行趙七。并沒有多創(chuàng)建出來pool-1-thread-5和pool-1-thread-6

?4、newScheduledThreadPool

創(chuàng)建一個(gè)定長(zhǎng)線程池,支持定時(shí)及周期性任務(wù)執(zhí)行

  • Executors.newScheduledThreadPool(int corePoolSize),corePoolSize表示線程容量。
  • schedule(Callable/Runnable command,long initialDelay,TimeUnit unit):第一個(gè)參數(shù)任務(wù),第二個(gè)參數(shù)表示執(zhí)行任務(wù)前等待的時(shí)間,第三參數(shù)表示時(shí)間單位。
  • scheduleAtFixedRate(Runnable command,long initialDelay,long period,TimeUnit unit):第一個(gè)參數(shù)表示周期線執(zhí)行的任務(wù),第二個(gè)參數(shù)表示第一次執(zhí)行前的延遲時(shí)間,第三個(gè)參數(shù)表示任務(wù)啟動(dòng)間隔時(shí)間,第四個(gè)參數(shù)表示時(shí)間單位。雖然任務(wù)類型是Runnable但該方法有返回值ScheduledFuture??梢酝ㄟ^該對(duì)象獲取線程信息。
  • scheduleWithFixedDelay(Runnable command,long initialDelay,long period,TimeUnit unit):與scheduleAtFixedRate方法類似,不同的是第三個(gè)參數(shù)表示前一次結(jié)束的時(shí)間和下一次任務(wù)啟動(dòng)的間隔時(shí)間

?示例

package executorservice.demo; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit;/*** @author boshen* @date 2018/12/20*/ public class ScheduledThreadPoolTest {class StudentThread implements Runnable{private String name;StudentThread(String name){this.name = name;}public void run(){try {System.out.println("學(xué)生:" + name + " 開始吃飯,線程名為:"+Thread.currentThread().getName());Thread.sleep(1000);}catch (InterruptedException e) {e.printStackTrace();}}}public static void main(String[] args){ScheduledThreadPoolTest cb = new ScheduledThreadPoolTest();ScheduledExecutorService executorService = Executors.newScheduledThreadPool(2);//當(dāng)以下線程提交后要2秒后才執(zhí)行,只執(zhí)行一次executorService.schedule(cb.new StudentThread("張三"),2000, TimeUnit.MILLISECONDS);//當(dāng)以下線程提交后要2秒后才執(zhí)行,每3秒執(zhí)行一次,直到調(diào)用了executorService.shutdown();executorService.scheduleWithFixedDelay(cb.new StudentThread("李四"),2,3,TimeUnit.SECONDS);try {Thread.sleep(20000);} catch (InterruptedException e) {e.printStackTrace();}executorService.shutdown();} } 學(xué)生:李四 開始吃飯,線程名為:pool-1-thread-2 學(xué)生:張三 開始吃飯,線程名為:pool-1-thread-1 學(xué)生:李四 開始吃飯,線程名為:pool-1-thread-2 學(xué)生:李四 開始吃飯,線程名為:pool-1-thread-2 學(xué)生:李四 開始吃飯,線程名為:pool-1-thread-2 學(xué)生:李四 開始吃飯,線程名為:pool-1-thread-2

?

三、ExecutorService的幾個(gè)方法區(qū)別

?1、execute(Runnable),無法取得返回值

public static void main(String[] args){ExecutorService executorService = Executors.newSingleThreadExecutor();executorService.execute(new Runnable() {public void run() {System.out.println("該異步任務(wù)無返回值");}});executorService.shutdown();}

2、submit(Runnable),返回一個(gè) Future 對(duì)象。這個(gè) Future 對(duì)象可以用來檢查 Runnable 是否已經(jīng)執(zhí)行完畢,但是也無法取得run方法里面想要返回的值因?yàn)閞un方法為void

public static void main(String[] args){ExecutorService executorService = Executors.newSingleThreadExecutor();Future future = executorService.submit(new Runnable() {public void run() {try {Thread.sleep(10000);System.out.println("該任務(wù)執(zhí)行了10秒");} catch (InterruptedException e) {e.printStackTrace();}}});System.out.println("主線程中獲取子線程的執(zhí)行狀態(tài):如果返回null表示執(zhí)行正確完成");try {System.out.println(future.get());//線程沒有執(zhí)行完之前,會(huì)阻塞在這里} catch (InterruptedException e) {e.printStackTrace();} catch (ExecutionException e) {e.printStackTrace();}executorService.shutdown();} 主線程中獲取子線程的執(zhí)行狀態(tài):如果返回null表示執(zhí)行正確完成 該任務(wù)執(zhí)行了10秒 null

3、submit(Callable),返回一個(gè) Future 對(duì)象。這個(gè) Future 對(duì)象可以返回線程中call方法里面return的對(duì)象

public static void main(String[] args){ExecutorService executorService = Executors.newSingleThreadExecutor();Future future = executorService.submit(new Callable() {public Object call() throws Exception {Thread.sleep(10000);System.out.println("該任務(wù)執(zhí)行了10秒");return "call 返回的值";}});System.out.println("主線程中獲取子線程的結(jié)果:");try {System.out.println(future.get());//線程沒有執(zhí)行完之前,會(huì)阻塞在這里} catch (InterruptedException e) {e.printStackTrace();} catch (ExecutionException e) {e.printStackTrace();}executorService.shutdown();} 主線程中獲取子線程的結(jié)果: 該任務(wù)執(zhí)行了10秒 call 返回的值

?

4、invokeAll(Collection<? extends Callable<T>> tasks),參數(shù)是加入線程池的所有Callable,返值是List<Future<T>>,表示返回執(zhí)行后的一系列Callable的執(zhí)行結(jié)果

?

package executorservice.demo;import java.util.ArrayList; import java.util.List; import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future;/*** @author Administrator* @date 2018/12/27*/ public class InvokeAllTest {class StudentThread implements Callable{private String name;StudentThread(String name){this.name = name;}public Object call() throws Exception{System.out.println("學(xué)生:" + name + " 開始吃飯,線程名為:"+Thread.currentThread().getName());return "result: 學(xué)生"+name+"吃完飯了";}}public static void main(String[] args){InvokeAllTest invokeAllTest = new InvokeAllTest();ExecutorService executorService = Executors.newCachedThreadPool();List<Callable<String>> callables = new ArrayList<Callable<String>>();callables.add(invokeAllTest.new StudentThread("張三"));callables.add(invokeAllTest.new StudentThread("李四"));callables.add(invokeAllTest.new StudentThread("王五"));callables.add(invokeAllTest.new StudentThread("馬六"));try { List<Future<String>> futures = executorService.invokeAll(callables);for(Future<String> future:futures){System.out.println(future.get());}} catch (InterruptedException e) {e.printStackTrace();} catch (ExecutionException e) {e.printStackTrace();}executorService.shutdown();} }

?

學(xué)生:張三 開始吃飯,線程名為:pool-1-thread-1 學(xué)生:王五 開始吃飯,線程名為:pool-1-thread-3 學(xué)生:李四 開始吃飯,線程名為:pool-1-thread-2 學(xué)生:馬六 開始吃飯,線程名為:pool-1-thread-4 result: 學(xué)生張三吃完飯了 result: 學(xué)生李四吃完飯了 result: 學(xué)生王五吃完飯了 result: 學(xué)生馬六吃完飯了

?

四、ExecutorService 關(guān)閉

ExecutorService 的 shutdown() 方法。并不會(huì)立即關(guān)閉,但它將不再接受新的任務(wù),而且一旦所有線程都完成了當(dāng)前任務(wù)的時(shí)候,ExecutorService 將會(huì)關(guān)閉。在 shutdown() 被調(diào)用之前所有提交給 ExecutorService 的任務(wù)都被執(zhí)行。

如果你想要立即關(guān)閉 ExecutorService,你可以調(diào)用 shutdownNow() 方法。這樣會(huì)立即嘗試停止所有執(zhí)行中的任務(wù),并忽略掉那些已提交但尚未開始處理的任務(wù)。無法擔(dān)保執(zhí)行任務(wù)的正確執(zhí)行。可能它們被停止了,也可能已經(jīng)執(zhí)行結(jié)束。

?

總結(jié)

以上是生活随笔為你收集整理的java Concurrent包学习笔记(一):ExecutorService的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。