1. 程式人生 > >Java多執行緒-停止執行緒

Java多執行緒-停止執行緒

停止執行緒是在多執行緒開發時很重要的技術點,掌握此技術可以對執行緒的停止進行有效的處理。停止執行緒在Java語言中不像break那麼幹脆,需要一些技巧性的處理。使用Java內建支援多執行緒的類設計多執行緒應用是很常見的事情,然而,多執行緒給開發人員帶來了一些新的挑戰,如果處理不好就會導致超出預期的行為並且難以定位錯誤。停止一個執行緒意味著線上程處理完任務之前停掉正在做的操作,也就是放棄當前的操作。雖然這看起來很簡單,但是必須做好防範措施,以便達到預期的效果。停止一個執行緒可以使用Thread.stop()方法,但是這個方法是不安全的(unsafe),並且是已被棄用作廢的(deprecated),在將來的Java版本中,這個方法將不可用或不被支援。

在Java中有以下3中方法可以終止正在執行的執行緒:

1、使用退出標誌,使執行緒正常退出,也就是當run方法完成後執行緒終止。

2、使用stop方法強行終止執行緒,但是不推薦使用此方法,因為stop和suspend及resume一樣,都是作廢過期的方法,使用它們可能產生不可預料的結果

3、使用interrupt方法中斷執行緒。

舉例:使用interrupt()方法來停止執行緒,但interrupt()方法的使用效果並不像for+break語句那樣,馬上就停止迴圈。呼叫interrupt()方法僅僅是在當前執行緒中打了一個停止的標記,並不是真的停止執行緒。

package com.js.stop;

public class MyThread extends Thread {
	@Override
	public void run(){
		super.run();
		for(int i = 0;i<500000;i++){
			System.out.println("i="+(i+1));
		}
	}
}

package com.js.stop;

public class Run {
	public static void main(String[] args){
		try {
			MyThread myThread = new MyThread();
			myThread.start();
			myThread.sleep(2000);
			myThread.interrupt();
		} catch (InterruptedException e) {
			System.out.println("main catch");
			e.printStackTrace();
		}
	}
}


從執行結果來看,呼叫interrupt方法並沒有停止執行緒。那麼,如何停止執行緒呢?

1、異常法

線上程中用for語句來判斷一下執行緒是否是停滯狀態,如果是,則後面的程式碼不再執行即可。

例如:

package com.js.demo2;

public class MyThread extends Thread{
	@Override
	public void run(){
		super.run();
		for(int i=0;i<500000;i++){
			if(this.interrupted()){
				System.out.println("已經是停止狀態了!我要退出了!");
				break;
			}
			System.out.println("i="+(i+1));
		}
	}
}

package com.js.demo2;

public class Run {
	public static void main(String[] args){
		try {
			MyThread myThread = new MyThread();
			myThread.start();
			Thread.sleep(2000);
			myThread.interrupt();
		} catch (InterruptedException e) {
			System.out.println("main catch");
			e.printStackTrace();
		}
		System.out.println("end!");
	}
}

上面的示例雖然停止了執行緒,但如果for下面還有語句,還是會繼續執行的。例如:
package com.js.demo2;

public class MyThread extends Thread{
	@Override
	public void run(){
		super.run();
		for(int i=0;i<500000;i++){
			if(this.interrupted()){
				System.out.println("已經是停止狀態了!我要退出了!");
				break;
			}
			System.out.println("i="+(i+1));
		}
		System.out.println("我被輸出,如果此程式碼是for又繼續執行,執行緒並未停止!");
	}
}

該如何解決語句繼續執行的問題呢?

繼續更新程式碼:

package com.js.demo2;

public class MyThread extends Thread{
	@Override
	public void run(){
		super.run();
		try {
			for(int i=0;i<500000;i++){
				if(this.interrupted()){
					System.out.println("已經是停止狀態了!我要退出了!");
					throw new InterruptedException();
				}
				System.out.println("i="+(i+1));
			}
			System.out.println("我在for下面");
		} catch (InterruptedException e) {
			System.out.println("進入MyThread.java類run方法中得catch了!");
			e.printStackTrace();
		}
	}
}

package com.js.demo2;

public class Run {
	public static void main(String[] args){
		try {
			MyThread myThread = new MyThread();
			myThread.start();
			Thread.sleep(2000);
			myThread.interrupt();
		} catch (InterruptedException e) {
			System.out.println("main catch");
			e.printStackTrace();
		}
		System.out.println("end!");
	}
}


2、在沉睡中停止

如果執行緒在sleep()狀態下停止執行緒,會是什麼效果呢?

例如:

package com.js.demo3;

public class MyThread extends Thread {
	@Override
	public void run(){
		super.run();
		try {
			System.out.println("run begin");
			Thread.sleep(200000);
			System.out.println("run end");
		} catch (InterruptedException e) {
			System.out.println("在沉睡中被停止!進入catch!"+this.isInterrupted());
			e.printStackTrace();
		}
	}
}

package com.js.demo3;

public class Run {
	public static void main(String[] args){
		try {
			MyThread myThread = new  MyThread();
			myThread.start();
			Thread.sleep(200);
			myThread.interrupt();
		} catch (InterruptedException e) {
			System.out.println("main catch");
			e.printStackTrace();
		}
	}
}

執行結果:

run begin
在沉睡中被停止!進入catch!false
java.lang.InterruptedException: sleep interrupted
at java.lang.Thread.sleep(Native Method)
at com.js.demo3.MyThread.run(MyThread.java:9)

從結果來看,如果在sleep狀態下停止某一執行緒,會進入catch語句,並且清楚停止狀態值,使之變成false。

前一個實驗是先sleep,然後再用interrupt停止,與之相反的操作在學習執行緒時也要注意:

package com.js.demo3;

public class MyThread extends Thread {
	@Override
	public void run(){
		super.run();
		try {
			for(int i=0;i<100000;i++){
				System.out.println("i="+(i+1));
			}
			System.out.println("run begin");
			Thread.sleep(200000);
			System.out.println("run end");
		} catch (InterruptedException e) {
			System.out.println("先停止,再遇到了sleep!進入catch!");
			e.printStackTrace();
		}
	}
}

package com.js.demo3;

public class Run {
	public static void main(String[] args){
		MyThread myThread = new MyThread();
		myThread.start();
		myThread.interrupt();
		System.out.println("end!");
	}
}


3、使用return停止執行緒

講方法interrupt()與return組合使用也能實現停止執行緒的效果

例如:

package com.js.demo4;

public class MyThread extends Thread {
	@Override
	public void run(){
		while(true){
			if(this.isInterrupted()){
				System.out.println("停止了!");
				return;
			}
			System.out.println("timer="+System.currentTimeMillis());
		}
	}
}

package com.js.demo4;

public class Run {

	public static void main(String[] args) throws InterruptedException {
		MyThread myThread = new MyThread();
		myThread.start();
		Thread.sleep(20000);
		myThread.interrupt();
	}

}


執行結果:

...

timer=1496394913416
timer=1496394913416
timer=1496394913416
timer=1496394913416
timer=1496394913416
timer=1496394913416
停止了!

不過還是建議使用“拋異常”的方法來實現執行緒的停止,因為catch塊中還可以將異常向上拋,使執行緒停止的事件得以傳播。

相關推薦

Java執行-停止執行

停止執行緒是在多執行緒開發時很重要的技術點,掌握此技術可以對執行緒的停止進行有效的處理。停止執行緒在Java語言中不像break那麼幹脆,需要一些技巧性的處理。使用Java內建支援多執行緒的類設計多執行緒應用是很常見的事情,然而,多執行緒給開發人員帶來了一些新的挑戰,如果處

執行——停止執行(結束run方法)

package com.qianfeng.demo01; /** * 停止執行緒: * 1.stop():已過時,這種方法有固有的不安全性,強制停止執行緒,不論處於什麼狀態都會停止,就會導致執行緒

java個例項物件執行同步無效的原因以及解決方案

【原因】:synchronized用法沒搞清楚 下面就直接舉例子了! 【情況1】:單例項物件多執行緒 public class Demo3 { Tlwindow twd1,twd2,twd3; //定義三個視窗 public static void

基礎篇:讓執行停止執行的幾種方式(七)

這篇文章我們來討論一下終止執行緒執行的方法; 中斷執行緒的方法: public static void stopThread() throws InterruptedException{ Thread t = new Thread(new Runnable() {

Java執行基礎之停止執行

JAVA中有3種終止正在執行的執行緒: 使用退出標誌,使執行緒正常的退出,也就是run方法執行完成後執行緒終止。 使用stop方式強行終止執行緒,但是不推薦使用這種方式,因為stop和suspend及resume一樣,都是作廢過期的方法,使用它們可能產生不可預料的後果。 使用i

Java執行停止不了的執行

    停止執行緒可以呼叫interrupt()方法,但是interrupt()方法的使用效果並不像for + break 語句那樣,馬上就停止迴圈。呼叫interrupt()方法僅僅是在當前執行緒中打了一個停止的標記。並不是真的停止執行緒。下面舉個例子: public cl

java執行】守護執行執行停止、volatile的深入瞭解

文章目錄 執行緒的優雅停止 守護執行緒 volatile關鍵字 執行緒的優雅停止       在多執行緒的操作之中如果要啟動多執

Java 執行 學習筆記(二)停止執行的幾種方法

1.異常法: package test; import exthread.MyThread; import exthread.MyThread; public class Run { pu

JAVA執行學習筆記 停止執行

在這裡要注意interrupt()方法,線上程正常執行的時候,呼叫 interrupt() 並不能結束執行緒。 正確的結束執行緒的姿勢如下: <span style="white-space:p

JAVA執行機制之暫停、恢復和停止

在JDK1.2以前的版本如果要實現執行緒的暫停、恢復和停止的方法分別是suspend()、resume()、stop()。但是從JDK1.2以後這些方法已經被遺棄,因為它們有可能造成嚴重的系統錯誤和異常。 首先suspend()方法不會釋放執行緒所佔用的資源。

java執行之使用interrupt停止執行的幾種方法

停止執行緒 停止執行緒是java多執行緒開發中很重要的技術點,實際工作中很多業務都有類似的需求,掌握此技術可以對業務中所需停止的執行緒做有效的處理。但是停止執行緒在java語言中並不像break語句中那樣乾脆簡單,還需要我們做一下技巧性的處理。 如何更好的停

Java執行學習(1)——停止執行

目錄: 1.interrupt方法學習(基礎知識) 2.異常法 3.sleep法 4.return法 5.stop法(不推薦) 1.interrupt方法學習(基礎知識) 呼叫interrupt方法只是對執行緒做了一個標記(停止標記),並沒有停止執行緒的效果,需要結合以下

Java執行實現電影院售票案例

某電影院目前正在上映賀歲大片,共有100張票,而它有3個售票視窗,請設計一個程式模擬該電影院售票。 定義Sell類實現Runnable介面,很好的解決了單繼承共享資源問題 public class Sell implements Runnable { // 定義100張票,三個售票

java執行物件鎖、類鎖、同步機制詳解

1.在java多執行緒程式設計中物件鎖、類鎖、同步機制synchronized詳解:     物件鎖:在java中每個物件都有一個唯一的鎖,物件鎖用於物件例項方法或者一個物件例項上面的。     類鎖:是用於一個類靜態方法或者class物件的,一個

Java 執行實現死鎖場景

簡述: 《Java 程式設計思想》  P718 ~ P722 模擬死鎖的場景, 三個人 三根筷子,每個人需要拿到身邊的兩根筷子才能開始吃飯 出現死鎖的場景是,三個人都拿到了右邊的筷子,但是由於筷子都被搶佔,均無法獲得左邊的筷子 Chopstick.java

Java 執行 join和interrupt 方法

簡述: 使用Java多執行緒中join和interrupt函式 《Java程式設計思想》 P669 ~ P670 一個執行緒可以再其他執行緒上呼叫join()方法,其效果是等待一段時間直到第二個執行緒結束才繼續執行。 如果某個執行緒在另一個執行緒t上呼叫t.join(), 此

Java 執行 CountDownLatch 試用

簡述: 使用Java多執行緒的庫,包括 ExecutorService執行緒池, CountDownLatch執行緒執行控制(知道所有啟動的執行緒呼叫完成後,函式才會繼續執行) package test.anialy.multithread; import java.ut

Java執行中Synchronized簡介和Static Synchronized的區別

在進行Java開發時,多執行緒的開發是經常會使用的。首先會問一個小問題啊,在Java中有幾種方法可以建立一個執行緒? 我給的答案是3種。(如果還有其他的請留言告訴我哈。) 1、建立直接繼承自Thread類建立執行緒子類。   步驟如下:a 定義一個子類,同時

Java執行學習與總結(Join)

join()方法的用法: join()是主執行緒 等待子執行緒的終止。也就是在子執行緒呼叫了 join() 方法後面的程式碼,只有等到子執行緒結束了才能執行。 例子如下: Java程式碼 p

Java執行學習與總結(ThreadGroup)

在Java中每個執行緒都屬於某個執行緒組(ThreadGroup)。例如,如果在main()中產生一個執行緒,則這個執行緒屬於main執行緒組管理的一員,您可以使用下面的指令來獲得目前執行緒所屬的執行緒組名稱: Java程式碼