多執行緒的使用——中斷執行緒詳解(Interrupt)
在JAVA中,曾經使用stop方法來停止執行緒,然而,該方法具有固有的不安全性,因而已經被拋棄(Deprecated)。那麼應該怎麼結束一個程序呢?官方文件中對此有詳細說明:《為何不贊成使用 Thread.stop、Thread.suspend 和 Thread.resume?》。在此引用stop方法的說明:
1. Why is Thread.stop deprecated? Because it is inherently unsafe. Stopping a thread causes it to unlock all the monitors that it has locked. (The monitors are unlocked as the ThreadDeath exception propagates up the stack.) If any of the objects previously protected by these monitors were in an inconsistent state, other threads may now view these objects in an inconsistent state. Such objects are said to be damaged. When threads operate on damaged objects, arbitrary behavior can result. This behavior may be subtle and difficult to detect, or it may be pronounced. Unlike other unchecked exceptions, ThreadDeath kills threads silently; thus, the user has no warning that his program may be corrupted. The corruption can manifest itself at any time after the actual damage occurs, even hours or days in the future. 大概意思是: 因為該方法本質上是不安全的。停止一個執行緒將釋放它已經鎖定的所有監視器(作為沿堆疊向上傳播的未檢查 ThreadDeath 異常的一個自然後果)。如果以前受這些監視器保護的任何物件都處於一種不一致的狀態,則損壞的物件將對其他執行緒可見,這有可能導致任意的行為。此行為可能是微妙的,難以察覺,也可能是顯著的。不像其他的未檢查異常,ThreadDeath異常會在後臺殺死執行緒,因此,使用者並不會得到警告,提示他的程式可能已損壞。這種損壞有可能在實際破壞發生之後的任何時間表現出來,也有可能在多小時甚至在未來的很多天後。 在文件中還提到,程式設計師不能通過捕獲ThreadDeath異常來修復已破壞的物件。具體原因見原文。 既然stop方法不建議使用,那麼應該用什麼方法來代理stop已實現相應的功能呢? 1、通過修改共享變數來通知目標執行緒停止執行- private Thread blinker;
- publicvoid start() {
- blinker = new Thread(this);
- blinker.start();
- }
- publicvoid stop() {
- blinker.stop(); // UNSAFE!
- }
- publicvoid run() {
- Thread thisThread = Thread.currentThread();
- while (true) {
- try {
- thisThread.sleep(interval);
- } catch (InterruptedException e){
- }
- repaint();
- }
- }
- private
- publicvoid stop() {
- blinker = null;
- }
- publicvoid run() {
- Thread thisThread = Thread.currentThread();
- while (blinker == thisThread) {
- try {
- thisThread.sleep(interval);
- } catch (InterruptedException e){
- }
- repaint();
- }
- }
- package com.polaris.thread;
- publicclass TestThread implements Runnable{
- boolean stop = false;
- publicstaticvoid main(String[] args) throws Exception {
- Thread thread = new Thread(new TestThread(),"My Thread");
- System.out.println( "Starting thread..." );
- thread.start();
- Thread.sleep( 3000 );
- System.out.println( "Interrupting thread..." );
- thread.interrupt();
- System.out.println("執行緒是否中斷:" + thread.isInterrupted());
- Thread.sleep( 3000 );
- System.out.println("Stopping application..." );
- }
- publicvoid run() {
- while(!stop){
- System.out.println( "My Thread is running..." );
- // 讓該迴圈持續一段時間,使上面的話列印次數少點
- long time = System.currentTimeMillis();
- while((System.currentTimeMillis()-time < 1000)) {
- }
- }
- System.out.println("My Thread exiting under request..." );
- }
- }
- package com.polaris.thread;
- publicclass TestThread2 implements Runnable{
- boolean stop = false;
- publicstaticvoid main(String[] args) throws Exception {
- Thread thread = new Thread(new TestThread2(),"My Thread2");
- System.out.println( "Starting thread..." );
- thread.start();
- Thread.sleep( 3000 );
- System.out.println( "Interrupting thread..." );
- thread.interrupt();
- System.out.println("執行緒是否中斷:" + thread.isInterrupted());
- Thread.sleep( 3000 );
- System.out.println("Stopping application..." );
- }
- publicvoid run() {
- while(!stop){
- System.out.println( "My Thread is running..." );
- // 讓該迴圈持續一段時間,使上面的話列印次數少點
- long time = System.currentTimeMillis();
- while((System.currentTimeMillis()-time < 1000)) {
- }
- if(Thread.currentThread().isInterrupted()) {
- return;
- }
- }
- System.out.println("My Thread exiting under request..." );
- }
- }
注意:interrupted與isInterrupted方法的區別(見API文件)
引用一篇文章
當外部執行緒對某執行緒呼叫了thread.interrupt()方法後,java語言的處理機制如下:
如果該執行緒處在可中斷狀態下,(呼叫了xx.wait(),或者Selector.select(),Thread.sleep()等特定會發生阻塞的api),那麼該執行緒會立即被喚醒,同時會受到一個InterruptedException,同時,如果是阻塞在io上,對應的資源會被關閉。如果該執行緒接下來不執行“Thread.interrupted()方法(不是interrupt),那麼該執行緒處理任何io資源的時候,都會導致這些資源關閉。當然,解決的辦法就是呼叫一下interrupted(),不過這裡需要程式設計師自行根據程式碼的邏輯來設定,根據自己的需求確認是否可以直接忽略該中斷,還是應該馬上退出。
如果該執行緒處在不可中斷狀態下,就是沒有呼叫上述api,那麼java只是設定一下該執行緒的interrupt狀態,其他事情都不會發生,如果該執行緒之後會呼叫行數阻塞API,那到時候執行緒會馬會上跳出,並丟擲InterruptedException,接下來的事情就跟第一種狀況一致了。如果不會呼叫阻塞API,那麼這個執行緒就會一直執行下去。除非你就是要實現這樣的執行緒,一般高效能的程式碼中肯定會有wait(),yield()之類出讓cpu的函式,不會發生後者的情況。
相關推薦
多執行緒的使用——中斷執行緒詳解(Interrupt)
在JAVA中,曾經使用stop方法來停止執行緒,然而,該方法具有固有的不安全性,因而已經被拋棄(Deprecated)。那麼應該怎麼結束一個程序呢?官方文件中對此有詳細說明:《為何不贊成使用 Thread.stop、Thread.suspend 和 Threa
多執行緒之Future使用詳解
什麼是Future Future是一個未來物件,裡面儲存這執行緒處理結果,它像一個提貨憑證,拿著它你可以隨時去提取結果 什麼時候使用 在兩種情況下,離開Future幾乎很難辦。 一種情況是拆分訂單,比如你的應用收到一個批量訂單,此時如果要求最快的處理訂單,那麼需要併發
Android 多執行緒之HandlerThread 完全詳解
之前對執行緒也寫過幾篇文章,不過倒是沒有針對android,因為java與android線上程方面大部分還是相同,不過本篇我們要介紹的是android的專屬類HandlerThread,因為HandlerThread在設定思想上還是挺值得我們學習的,那麼我們下面來
Java多執行緒Condition介面原理詳解
Condition介面提供了類似Object的監視器方法,與Lock配合可以實現等待/通知模式,但是這兩者在使用方式以及功能特性上還是有差別的 Condition介面詳解 Condition定義了等待/通知兩種型別的方法,當前執行緒呼叫這些方法時,需要提前獲
多執行緒之重排序詳解
重排序 重排序是指編譯器和處理器為了優化程式效能而對指令序列進行重新排序的一種手段。 資料依賴性 如果兩個操作訪問同一個變數,且這兩個操作中有一個為寫操作,此時這兩個操作之間就存在資料的依賴性。資料依賴分為3中型別,如下表所示: 上面3中情況,只要重排序兩個操作的順序。程式的結
C#基礎系列:多執行緒的常見用法詳解
前言:此篇就主要從博主使用過的幾種多執行緒的用法從應用層面大概介紹下。文中觀點都是博主個人的理解,如果有不對的地方望大家指正~~ 1、多執行緒:使用多個處理控制代碼同時對多個任務進行控制處理的一種技術。據博主的理解,多執行緒就是該應用的主執行緒任命其他多個執行緒去協
Android 多執行緒程式設計之 HandlerThread 詳解
HandlerThread有那些特點: HandlerThread本質上是一個執行緒類,它繼承了Thread; HandlerThread有自己的內部Looper物件,可以進行looper迴圈; 通過獲取HandlerThread的looper物件傳
Java多執行緒同步和非同步詳解
1. 多執行緒併發時,多個執行緒同時請求同一資源,必然導致此資源的資料不安全。 2. 執行緒池 在WEB服務中,對於web伺服器的響應速度必須儘可能的快,這就容不得在使用者提交請求按鈕後,再建立執行緒提供服務。為了減少使用者的等待時間,執行緒必須預先建立,放線上程池中,執行
入坑JAVA多執行緒併發(八)詳解ThreadLocal使用和原理
ThreadLocal是一個用於儲存多執行緒變數的類,它可以把執行緒與設定的值對應起來,因為它為變數在每個執行緒都建立了一個副本。訪問的時候每個執行緒只能訪問到自己的副本變數。 例項 看如下程式碼: public class Main {
C#基礎系列——多執行緒的常見用法詳解
前言:前面幾節分別介紹了下C#基礎技術中的反射、特性、泛型、序列化、擴充套件方法、Linq to Xml等,這篇跟著來介紹下C#的另一基礎技術的使用。最近專案有點緊張,所以準備也不是特別充分。此篇就主要從博主使用過的幾種多執行緒的用法從應用層面大概介紹下。文中觀點都是博主個人的理解,如果有不對的地方望大家指正
JAVA多執行緒Thread VS Runnable詳解
要求 必備知識 本文要求基本瞭解JAVA程式設計知識。 開發環境 windows 7/EditPlus 演示地址 原始檔 程序與執行緒 程序是程式在處理機中的一次執行。一個程序既包括其所要執行的指令,也包括了執行指令所需的系統資源,不同程序所
多執行緒之 Final變數 詳解
原文: http://www.tuicool.com/articles/2Yjmqy 併發程式設計網:http://ifeve.com/java-memory-model/ 總結: Final 變數在併發當中,原理是通過禁止cpu的指令集重排序(重排序詳解http://ifeve.com/java
Java 多執行緒之synchronized關鍵字詳解
package com.example; /** * Created by 晁東洋 on 2017/5/27. */ public class MyThreadClass { public static void main(String args[]){ Exampletest
【多執行緒】執行緒互斥之synchronized 詳解
定義: 執行緒互斥是指某一資源同時只允許一個訪問者對其進行訪問,具有唯一性和排它性。但互斥無法限制訪問者對資源的訪問順序,即訪問是無序的。 我們都知道保證執行緒完整執行。則需要對其加鎖。使用synchronized關鍵字。在這裡鎖的物件理論上可以為任何物件。
java多執行緒與併發程式設計詳解
一、多執行緒1、作業系統有兩個容易混淆的概念,程序和執行緒。程序:一個計算機程式的執行例項,包含了需要執行的指令;有自己的獨立地址空間,包含程式內容和資料;不同程序的地址空間是互相隔離的;程序擁有各種資源和狀態資訊,包括開啟的檔案、子程序和訊號處理。執行緒:表示程式的執行流程
Python多程序與多執行緒程式設計及GIL詳解
介紹如何使用python的multiprocess和threading模組進行多執行緒和多程序程式設計。 Python的多程序程式設計與multiprocess模組 python的多程序程式設計主要依靠multiprocess模組。我們先對比兩段程式碼,看看多程序程式設計的優勢。我們模擬了一個非常耗時的任
Python程序、執行緒、協程詳解、執行效能、效率(tqdm)
多程序實踐——multiprocessing 筆者最近在實踐多程序發現multiprocessing,真心很好用,不僅加速了運算,同時可以GPU呼叫,而且互相之間無關聯,這樣可以很放心的進行計算。 譬如(參考:多程序): from multiprocessing import Pool
Java執行緒池Executor框架詳解
Java的執行緒既是工作單元,也是執行機制。從JDK 5開始,把工作單元與執行機制分離開來。工作單元包括Runnable和Callable,而執行機制由Executor框架提供。 Executor框架簡介在HotSpot VM的執行緒模型中,Java執行緒(java.lang.Thread)被一對一對映為本
美團面試題:Java-執行緒池 ThreadPool 專題詳解
去美團面試,問到了什麼是執行緒池,如何使用,為什麼要用,以下做個總結。關於執行緒之前也寫過一篇文章《高階面試題總結—執行緒池還能這麼玩?》 1、什麼是執行緒池: java.util.concurrent.Executors提供了一個 java.util.conc
java執行緒(上)——執行緒狀態及屬性詳解
在作業系統中,我們通過分時的方法在CPU上不斷地切換處理多個程序任務,給人並行處理的感覺,這種方法在作業系統中叫做多工。多工在較低層次上擴展出多執行緒的概念,也就是指一個程式同時執行多個執行緒。這種可以同時執行一個以上的執行緒的程式,我們叫做多執行緒程式。