1. 程式人生 > >Java停止一個執行緒的幾種方法

Java停止一個執行緒的幾種方法

Java中停止一個執行緒有三種方法,分別是stop,interrupt和設定標誌位,我們依次來看一下這三種方法。

首先不推薦使用stop方法,原因有兩點:

1、原則上只要一呼叫thread.stop()方法,執行緒就會立即停止,並丟擲ThreadDeath error,查看了Thread的原始碼後發現,原先Thread.stop0()方法是同步的,而如果我們工作執行緒的run()方法也是同步,那麼這樣會導致主執行緒和工作執行緒共同爭用同一個鎖(工作執行緒物件本身),由於工作執行緒在啟動後就先獲得了鎖,所以無論如何,當主執行緒在呼叫t.stop()時,它必須要等到工作執行緒的run()方法執行結束後才能進行,結果會使及時性收到影響。

2、thread.stop()是不安全的。它的不安全主要是針對於在停止該執行緒時會釋放該執行緒所持有的所有的鎖。一般任何進行加鎖的程式碼塊,都是為了保護資料的一致性,如果在呼叫thread.stop()後導致了該執行緒所持有的所有鎖的突然釋放,那麼被保護資料就有可能呈現不一致性,其他執行緒在使用這些被破壞的資料時,有可能導致一些很奇怪的應用程式錯誤。

我們來看interrupt的方法

首先貼一段程式碼:

class MyThread04 extends Thread {  
     
   public MyThread04(String threadName) {  
       super(threadName);  
   }  

   @Override 
   public void run() {  
         try{
        	 for (int j = 0; j<100; j++) {  
                 if(this.isInterrupted()) throw new InterruptedException();
                 System.out.println(Thread.currentThread().getName()+":"+j);
                 Thread.sleep(10000);
        	 }
        	 
         }catch (InterruptedException e) {  
//             e.printStackTrace();  
         }  
       
          
       }  
         
}

或者是像下面這樣寫,try.catch塊的範圍較小,更利於調優

class MyThread04 extends Thread {
	public MyThread04(String threadName) {
		super(threadName);
	}

	@Override
	public void run() {
		// try{
		for (int j = 0; j < 100; j++) {
			if (this.isInterrupted())
				break;
			System.out.println(Thread.currentThread().getName() + ":" + j);
			try {
				Thread.sleep(10000);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				this.interrupt();// 由於處於sleep狀態的執行緒被終止後會將標誌位復位,所以需要重設一次
				e.printStackTrace();
			}
		}
	}
}


這裡之所以丟擲異常並捕獲是考慮到對一個處於wait或者sleep狀態的執行緒使用interrupt是會丟擲異常的,所以需要事先捕獲,主程序程式碼如下:

MyThread04 t=new MyThread04("A");
		t.start();
		try {
			Thread.sleep(5000);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		t.interrupt();
}

使用interrupt()方法優雅的結束了程序。

我們最後看看設定標誌位的方法,程式碼如下:

class MyThread04 extends Thread {

	private boolean stop = false;

	public MyThread04(String threadName) {
		super(threadName);
	}

	@Override
	public void run() {

		for (int j = 0; j < 100; j++) {
			if (this.stop == false) {
				System.out.println(Thread.currentThread().getName() + ":" + j);
				try {
					Thread.sleep(1000);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			} else {
				break;
			}

		}

	}

	public void setStop() {
		this.stop = true;
	}
}

只要在主程序中呼叫setStop()方法就可以了,但此時如果for迴圈之後仍有程式碼,那麼這些程式碼還是會被執行,為了避免這一點,我們可以採用丟擲異常的方式處理,程式碼如下:

class MyThread04 extends Thread {

	private boolean stop = false;

	public MyThread04(String threadName) {
		super(threadName);
	}

	@Override
	public void run() {

		try{
			for (int j = 0; j < 100; j++) {
				if (this.stop == false) {
					System.out.println(Thread.currentThread().getName() + ":" + j);
					try {
						Thread.sleep(1000);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				} else {
					throw new InterruptedException();
				}

			}
			
		}catch (InterruptedException e) {
			e.printStackTrace();
		}
		

	}

	public void setStop() {
		this.stop = true;
	}
}


相關推薦

Java停止一個執行方法

Java中停止一個執行緒有三種方法,分別是stop,interrupt和設定標誌位,我們依次來看一下這三種方法。 首先不推薦使用stop方法,原因有兩點: 1、原則上只要一呼叫thread.stop()方法,執行緒就會立即停止,並丟擲ThreadDeath error,查看

android 終止執行方法

其實android 不提倡我們終止執行緒的,以前的一些函式,stop等等都不推薦使用了,但是當我們確實要終止執行緒的時候,可看考下面的問題 有時當一個元件或者activity被destory()的時候要求其啟動的執行緒也一起終止掉,現在就來總結了一下有這有幾種方法:

java建立一個執行的兩方法及區別

第一種方法:繼承Thread類 public class NewThread extends Thread { public void run() { for(int i=0;i<20;i++) { System.out.println(i); } } }

java刪除字串最後一個字元的方法

字串:string s = "1,2,3,4,5,"  目標:刪除最後一個 ","  方法:     1、用的最多的是Substring,這個也是我一直用的        

JAVA 建立一個執行的三方式

建立多執行緒-實現Runnable介面 建立類Battle,實現Runnable介面 啟動的時候,首先建立一個Battle物件,然後再根據該battle物件建立一個執行緒物件,並啟動   Battle battle1 = new Battle(gareen,teemo); new Thread(battle1

Java動態載入一個類的方法以及invoke

一.載入一個類的幾種方法 介面 IUser package org.me.javaapp; /** * * @author Administrator */ public interface IUser { } User.java /* * To

Linux 技巧:讓進程在後臺可靠執行方法

stl 選項 con 中斷 program ng- dem 不同 正在 我們常常會碰到這種問題。用 telnet/ssh 登錄了遠程的 Linux server,執行了一些耗時較長的任務, 結果卻因為網絡的不穩定導致任務中途失敗。怎樣讓命令提交後不受本地關閉終端

java寫入文件的方法分享

java一、FileWritter寫入文件 FileWritter,字符流寫入字符到文件。默認情況下,它會使用新的內容取代所有現有的內容,然而,當指定一個真(布爾)值作為FileWritter構造函數的第二個參數,它會保留現有的內容,並追加新內容在文件的末尾。 替換所有現有的內容與新的內容。

在頁面中隱藏一個元素的方法

osi play hid abs 隱藏 一個 bili cit eight 1.display:none,不占據空間,無法點擊; 2.visibility:hidden,占據空間,無法點擊; 3.height:0; overflow:hidden,不占據空間,無法點擊; 4

c#除掉字符串最後一個字符方法

要去 參數 aaa style log int print mov www 有一數組;轉換為字符串後為 aaa|bbb|ccc|ddd|現要去掉最後一個|第一種方法:語句為:str1=aaa|bbb|ccc|ddd|str=str1.substring(0,lastinde

java word轉pdf的方法

轉載:https://blog.csdn.net/qwert678000/article/details/72770109 最近公司需要以word為模版,填充資料,然後轉成pdf。做了一點點研究 1.使用xdocreport進行轉(優點效率高,缺點對word格式要求較大,適合對生成pdf要求

JAVA定義一個執行池,迴圈遍歷list

文章目錄 前言 思路 下面是我自己專案中的呼叫程式碼,供你參考(ProcessNumTask就是那個實現Callable的任務): Callable與Future的介紹 Callable的介面定義如下:

Java 獲取當前日期的方法

import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Date; public class getCurrDate { public st

java併發之----執行的建立方法

一、執行緒的建立 (1)繼承Thread類 需要實現run方法,通過呼叫start方法啟動執行緒 public class MyThread extends Thread{ @Override public void run(){//實現run方法 //以下根據自己的需要

java實現動態編譯的方法

所謂動態編譯,就是在程式執行時產生java類,並編譯成class檔案。 import java.io.BufferedReader; import java.io.InputStream; im

一、多執行基礎概念、實現執行方法、中斷執行方法,以及執行狀態轉化

1、CPU核心數和執行緒數的關係 1:1的關係,引入超執行緒之後,就是1:2 2、cpu時間輪轉機制,即RR排程 3、程序和執行緒 程序:程式執行資源分配最小單位,程序內部有多個執行緒,多個執行緒之間會共享程序資源 執行緒:CPU排程的最小單位 4、並行和併發

JAVA獲得當前時間的方法

package com.xjp.common.util; import java.sql.Timestamp;import java.text.ParsePosition;import java.text.SimpleDateFormat;import java.util.D

(轉)java向MySQL插入當前時間的四方式和java時間日期格式化的方法(案例說明)

轉載地址  https://www.cnblogs.com/zhaotiancheng/p/6413067.html 資料庫操作經常會用到時間,例如start_time,end_time,(在資料庫中是datetime型別,) 對應關係 mys

Java 延時常見的方法

1、 用Thread就不會iu無法終止 new Thread(new Runnable() { public void run() { while (true) { test(

java中獲取時間的方法

1. 通過Date類來獲取當前時間 Date day=new Date(); SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm: