執行緒停止(stop/intrrupt)
阿新 • • 發佈:2018-11-12
使一個執行緒停止有下列三種方式:
- 使用標記位(設定flag)停止執行緒;
- 呼叫stop方法強制停止執行緒;
- Thread類的interrupt方法;
一:使用falg停止執行緒
////使用標記位
class Mythread3 implements Runnable
{
private boolean flag=true;
public void run()
{
int i=1;
while(flag)
{
try {
Thread. sleep(1000);
System.out.println(i+"次進入for迴圈" );
i++;
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public void setFlag(boolean flag) {
this.flag = flag;
}
}
public class Stop1
{
public static void main(String[] args) throws InterruptedException {
Mythread3 thread=new Mythread3();
Thread thread1=new Thread(thread,"子執行緒");
thread1.start();
Thread.sleep(4000); //主執行緒4秒後會將thread1的falg置false,那麼就會推出迴圈,子執行緒就會停止
thread.setFlag(false);
}
}
二:用stop使執行緒停止
////使用stop
class Mythread3 implements Runnable
{
private boolean falg=true;
public void run()
{
System.out.print("子執行緒執行時間");
Stop1.printTime();
int i=1;
while(true)
{
try {
Thread.sleep(1000);
System.out.print("子執行緒第"+i+"次進入for迴圈時間");
Stop1.printTime();
i++;
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class Stop1
{
public static void main(String[] args) throws InterruptedException {
Mythread3 thread=new Mythread3();
Thread thread1=new Thread(thread,"子執行緒");
thread1.start();
System.out.println("");
System.out.println("");
System.out.print("子執行緒stop前4秒時間:");
printTime();
Thread.sleep(4000); //主執行緒4秒後會將執行thread1.stop,使子執行緒停止
thread1.stop(); //其實stop已經被過期宣告
System.out.print("子執行緒結束時間:");
printTime();
}
public static void printTime()
{
Date date=new Date();
DateFormat dateFormat=new SimpleDateFormat(("yyyy-MM-dd HH:mm:ss"));
String time=dateFormat.format(date);
System.out.println(time);
}
}
為什麼stop會被過期宣告呢??
因為stop不安全:stop會解除由執行緒獲取的所有鎖定,當在一個執行緒物件上呼叫stop()方法時,這個執行緒物件所執行的執行緒就會立即停止,假如一個執行緒正在執行:synchronized void { x = 3; y = 4;} 由於方法是同步的,多個
執行緒訪問時總能保證x,y被同時賦值,而如果一個執行緒正在執行到x = 3;時,被呼叫了 stop()方法,即使在同步塊中,它也會馬上stop了,這樣就產生了不完整的殘廢資料。
三.呼叫Thread類的interrupt方法
interrupt方法只是將執行緒狀態置為中斷而已,它不會中斷一個正在執行的執行緒。此方法只是給執行緒傳遞一箇中斷訊號,程式可以根據此訊號判斷是否要終止執行緒。
interrupt會拋異常:當執行緒中使用wait/sleep/jion方法導致執行緒阻塞,則interrupt會線上程中拋一個InterruptException,並且將執行緒的中斷狀態由true置為false。
////使用Thread.interupt方法
class Mythread3 implements Runnable
{
public void run() {
int i = 1;
while (true) {
try {
Thread.sleep(1000);
boolean bool = Thread.currentThread().isInterrupted();//當前執行緒是否被置為中斷狀態,是返回ture
//如果狀態被置為中斷狀態,並且處於阻塞狀態,會拋異常java.lang.InterruptedException,catch處理異常,不會走這個if語句
if (bool) {
System.out.println("非阻塞情況下執行該操作....執行緒狀態" + bool);
break;
}
System.out.println("第" + i + "次執行,執行緒名稱為:" + Thread.currentThread().getName());
i++;
} catch (InterruptedException e) {
//拋異常後,中斷標誌被系統會自動清除,執行緒中斷狀態由true變為false
boolean bool = Thread.currentThread().isInterrupted();
System.out.println(bool); //false
return; //退出run方法
}
}
}
}
public class Stop1
{
public static void main(String[] args) throws InterruptedException {
Mythread3 thread = new Mythread3();
Thread thread1 = new Thread(thread, "子執行緒");
thread1.start();
Thread.sleep(4000);
thread1.interrupt();//現線上程thread1為中斷狀態
}
}