摘要:文本將介紹兩種可以優雅的終止線程的方式第一種在多線程模式中有一種叫兩步終止的模式可以優雅的終止線程,這種模式采用了兩個步驟來終止線程,所以叫兩步終止模式。
第一種Java中原來在Thread中提供了stop()方法來終止線程,但這個方法是不安全的,所以一般不建議使用。文本將介紹兩種可以優雅的終止線程的方式...
在JAVA《Java多線程模式》中有一種叫Two-Phase Termination(兩步終止)的模式可以優雅的終止線程,這種模式采用了兩個步驟來終止線程,所以叫兩步終止模式。
先將執行標志位isShutdown 設為false,使工作中的線程轉變為終止處理中的狀態
真正去執行終止操作,這樣的做法可以保證線程的安全性、生命性和響應性。
class Worker extends Thread { private volatile boolean isShutdown = true; public void shutdown() { System.out.println("接收到關閉通知......"); this.isShutdown = false; interrupt(); } @Override public void run() { while (this.isShutdown) { System.out.println("正在工作:" + System.currentTimeMillis()); try { Thread.sleep(1000); } catch (InterruptedException e) { System.out.println("打斷正在工作的線程......"); } } System.out.println("銷毀......"); } } public class ThreadClose { public static void main(String[] args) throws InterruptedException { Worker worker = new Worker(); worker.start();//開始工作 Thread.sleep(3 * 1000); worker.shutdown();//優雅關閉 } }
運行日志
正在工作:1505828036769 正在工作:1505828037770 正在工作:1505828038771 接收到關閉通知...... 打斷正在工作的線程...... 銷毀......
安全性:不會在線程正在執行關鍵區域--Critical Section的時候突然結束掉
生命性:一定會進行終止處理,shutdown()中,會調用interrupt(),保證即使線程處于sleep或wait狀態也可以被立即終止
響應性:將isShutdown 設為volatile ,能保證線程收到終止請求后,會盡快開始終止處理。
存在的問題:針對沒有阻塞的情況:設置標志變量,讓線程正常自然死亡,和諧!,但是如果在調用shutdown發生阻塞情況呢?
第二種在 《多線程第一章》的時候,介紹過守護線程的作用,那么是不是可以通過開啟守護線程的方式去監聽
功能1.當工作結束就關閉主線程(主線程銷毀守護線程也會跟著一同銷毀)
2.如果任務長時間未完成,停止工作任務,減少開銷
1.定義主線程與發送的指令
2.在主線程run方法中創建一個守護線程,用來執行我們投遞的任務
3.前面已經介紹過join的功能,它可以阻塞主線程,等待子線程完成后主線程繼續執行
4.如果join釋放后,發送完成指令
private Thread executeService; private volatile boolean finished = false; public void execute(Runnable task) { executeService = new Thread(() -> { Thread runner = new Thread(task); runner.setDaemon(true); runner.start(); try { runner.join();//前面已經說過join與線程了 finished = true; } catch (InterruptedException e) { System.out.println("打斷正在工作的線程......"); } }); executeService.start(); }
5.創建listener(long mills),監聽工作情況
6.監聽任務是否完成,如果未完成監聽當前是否逾期,逾期打斷線程結束監聽
public void listener(long mills) { System.out.println("開啟監聽......"); long currentTime = System.currentTimeMillis(); while (!finished) { if ((System.currentTimeMillis() - currentTime) >= mills) { System.out.println("工作耗時過長,開始打斷..."); executeService.interrupt();//打斷線程 break; } try { executeService.sleep(100L);//每隔100毫秒檢測一次 } catch (InterruptedException e) { e.printStackTrace(); } } }
7.測試
public static void main(String[] args) { WorkerService service = new WorkerService(); long start = System.currentTimeMillis(); service.execute(() -> { try { Thread.sleep(3 * 1000);// TODO 模擬加載數據 } catch (InterruptedException e) { e.printStackTrace(); } }); service.listener(4 * 1000); System.out.println("一共耗時:" + (System.currentTimeMillis() - start)); }
listener(4 * 1000) 的運行日志,當任務完成會直接退出,并不會一直占用
開啟監聽...... 一共耗時:3049
listener(2 * 1000) 的運行日志,當任務超時直接打斷線程,減少資源占用
開啟監聽...... 工作耗時過長,開始打斷... 一共耗時:2050 打斷正在工作的線程......- 說點什么
全文代碼:https://gitee.com/battcn/battcn-concurent/tree/master/Chapter1-1/battcn-thread/src/main/java/com/battcn/chapter4
個人QQ:1837307557
battcn開源群(適合新手):391619659
微信公眾號:battcn(歡迎調戲)
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/67630.html
摘要:在退出時執行必要的挽救措施。在這種情況下,一旦被提供,等待一個進程終止指定的時間。如果進程在該時間限制內沒有終止,則通過發出或中的對等方強制終止進程。所以有可能這是在中途執行時發生的。 shutdownHook是一種特殊的結構,它允許開發人員插入JVM關閉時執行的一段代碼。這種情況在我們需要做特殊清理操作的情況下很有用 用途 在Jboss,Jetty等容器中都可以看到shutdown...
摘要:并且,線程池在某些情況下還能動態調整工作線程的數量,以平衡資源消耗和工作效率。同時線程池還提供了對池中工作線程進行統一的管理的相關方法。 開發中經常會遇到各種池(如:連接池,線程池),它們的作用就是為了提高性能及減少開銷,在JDK1.5以后的java.util.concurrent包中內置了很多不同使用場景的線程池,為了更好的理解它們,自己手寫一個線程池,加深印象。 概述 1.什么是...
摘要:在之前,不能為線程單獨設置或指定一個默認的,為了設置,需要繼承并覆寫方法。幸運的是后線程提供了一個方法,用來捕獲并處理因線程中拋出的未知異常,以避免程序終止。 在單線程的開發過程中,通常采用try-catch的方式進行異常捕獲,但是這種方式在多線程環境中會顯得無能為力,而且還有可能導致一些問題的出現,比如發生異常的時候不能及時回收系統資源,或者無法及時關閉當前的連接... 概述 Ja...
摘要:在前面的文章中介紹過觀察者模式及并發編程的基礎知識,為了讓大家更好的了解觀察者模式故而特意寫了這篇番外概述在多線程下我們需要知道當前執行線程的狀態是什么比如運行,關閉,異常等狀態的通知,而且不僅僅是更新當前頁面。 在前面的文章中介紹過 觀察者模式 及 并發編程的基礎知識,為了讓大家更好的了解觀察者模式故而特意寫了這篇番外.. 概述 在Java多線程下,我們需要知道當前執行線程的狀態是...
摘要:當時,會進入循環,系統會判斷主線程是否處于活躍狀態,如果處于活躍狀態,主線程就會不停的等待。 由于前段時間比較忙,線程這快學習停滯了,只能利用周日的時間來寫寫博客了,多線程Join方法的作用就是把指定的線程加入到當前線程,讓主線程等待子線程結束之后才能繼續運行,從而完成同步操作 介紹 join() 的作用:讓主線程等待子線程結束之后才能繼續運行,首先先來看下以采集為案例的代碼,統計采...
閱讀 3064·2021-10-12 10:20
閱讀 2809·2021-09-27 13:56
閱讀 790·2021-09-27 13:36
閱讀 1424·2021-09-26 09:46
閱讀 2417·2019-08-30 14:02
閱讀 2685·2019-08-28 18:14
閱讀 1257·2019-08-26 10:32
閱讀 1700·2019-08-23 18:25