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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

利用线程池为线程创建一个守护线程

發布時間:2025/1/21 编程问答 41 豆豆
生活随笔 收集整理的這篇文章主要介紹了 利用线程池为线程创建一个守护线程 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

主線程:

public class MainThread implements Callable {SimpleDateFormat sdf =new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS" );@Overridepublic Integer call() throws Exception {for (int i = 0; i < 10; i++) {Thread.sleep(200*i);Date now= new Date();System.out.println(Thread.currentThread() +":"+sdf.format(now));}return 0;} }

守護線程:

public class DeamonThread implements Callable<String> {private Future<Integer> mainThread;SimpleDateFormat sdf =new SimpleDateFormat("yyyy-MM-dd HH:mm:ss" );public DeamonThread() {}public DeamonThread(Future<Integer> mainThread) {this.mainThread = mainThread;}@Overridepublic String call() throws Exception {try{//如果主線程已執行完,則不在這里浪費時間if(!mainThread.isDone() || !mainThread.isCancelled()){//如果主線程執行超過2s,執行守護線程finally語句內代碼Thread.sleep(2000);System.out.println("守護線程等待了2s");}}catch (InterruptedException e){}finally {if(!mainThread.isDone() || !mainThread.isCancelled()){mainThread.cancel(true);}System.out.println("主線程執行超時,主線程結束");}return "";} }

測試:

public class ThreadPoolDemo {public static void main(String[] args) {ThreadPoolExecutor threadPoolExecutor = null;try {MainThread mainThread = new MainThread();threadPoolExecutor = new ThreadPoolExecutor(2, 2, 10, TimeUnit.SECONDS, new LinkedBlockingQueue<>(1));Future<Integer> mainResult = threadPoolExecutor.submit(mainThread);DeamonThread deamonThread1 = new DeamonThread(mainResult);threadPoolExecutor.submit(deamonThread1);System.out.println("*****"+mainResult.get()+"*****");}catch (Exception e){}finally {if(threadPoolExecutor!=null){threadPoolExecutor.shutdown();}}} }

主線程執行超過2s任務被取消:

細心的話可以發現:

System.out.println("*****"+mainResult.get()+"*****");

這句代碼沒執行,查看原因


可以看出是調用mainResult.get()方法時發生CancellationException異常(由于任務執行中斷,被取消)

Future<Integer> mainResult = threadPoolExecutor.submit(mainThread); DeamonThread deamonThread1 = new DeamonThread(mainResult); threadPoolExecutor.submit(deamonThread1);

另外,線程池中,不同任務間是競爭執行的,不會按代碼順序去一步一步執行,所以守護線程可以在主線程執行過程中得到主線程返回的Future mainResult對象。
除了多線程任務執行無序,事實上當前main方法線程和線程池中的多線程任務也會并發執行,修改部分代碼:


可以看出,先把main方法中for循環代碼執行了(耗時較短,瞬間執行完畢,如果與線程池任務耗時相當,則可看見交替執行效果),而System.out.println("*****"+mainResult.get()+"*****");后邊的for語句因為get()方法拋異常,未被執行。而get()方法本身是個阻塞方法,是在線程池任務結束后才執行的,以便獲取實際返回值(畢竟線程任務如果是查詢任務,我們需要其實際返回值)。

總結

以上是生活随笔為你收集整理的利用线程池为线程创建一个守护线程的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。