如何關掉一個線程

1、Thread.stop()java

此方法已通過時,不推薦了。。。安全

由於它本質上是不安全的。中止線程會致使它解鎖全部已鎖定的監視器。(當ThreadDeath異常在堆棧中傳播時,監視器被解鎖。)若是以前由這些監視器保護的對象中的任何一個處於不一致狀態,則其餘線程如今能夠以不一致的狀態查看這些對象。據稱這些物體被 損壞。當線程操做受損對象時,可能致使任意行爲。就比如電腦的冷關機,或者忽然斷電。沒有作任務的保護措施!可能會讓你丟失數據。。。因此稱之爲不安全的!ide

public class Test {
    private int lock = 1;
    public void volatileTest() {
        Runnable runnable1 = new Runnable() {
            @Override
            public void run() {
                int n = 0;
                while (lock == 1){
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println("T1--"+ n++ +":runnable is running...");
                }
                System.out.println("T1--"+ n+":runnable is run out...");
            }
        };
        Runnable runnable2 = new Runnable() {
            @Override
            public void run() {
                int n = 0;
                while (lock == 1){
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println("T2--"+ n++ +":runnable is running...");
                }
                System.out.println("T2--"+ n+":runnable is run out...");
            }
        };
        Thread t1 =  new Thread(runnable1);
        Thread t2 =  new Thread(runnable2);
        t1.start();
        t2.start();
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        t1.stop();  //你再鍵入這個方法時候,IDE會提醒你這個方法如今已通過時,不推薦了!

    }
}

2、利用volatile的可見性做爲開關控制器函數

詳見另外一篇文章的描述:http://www.javashuo.com/article/p-gwsefwld-cx.htmlspa

3、Thread.interrupt()/isInterrupted/interrupted配合的信號。使得線程被中斷拋出異常!.net

1)RUNNING狀態線程—>先被阻塞成BLOCKED->再被中斷—>flag=true!線程

2) RUNNING狀態線程—>先被中斷—>flag = true—>若再被阻塞—>flag = false!code

3)interrupted()方法先返回當前的狀態flag(無論是true仍是false),同時又把標誌位清除爲false(無論以前是true仍是false)對象

4)isInterrupted()方法只是返回當前的flag狀態,不作任務賦值處理!blog

5)interrupted和isInterrupted的最大區別在於他們的源碼定義中,一個傳入清除參數爲true,另外一個傳入爲false!

 

 

 

 

其實Thread.interrupt功能意圖是讓阻塞BLOCKED的線程被中斷掉

isInterrupted()源碼,其中false表示不清楚標誌位!

public boolean isInterrupted() {
    return isInterrupted(false);
}

要中斷一個Java線程,可調用線程類(Thread)對象的實例方法:interrupte();然而interrupte()方法並不會當即執行中斷操做;具體而言,這個方法只會給線程設置一個爲true的中斷標誌(中斷標誌只是一個布爾類型的變量),而設置以後,則根據線程當前的狀態進行不一樣的後續操做。若是,線程的當前狀態處於非阻塞狀態,那麼僅僅是線程的中斷標誌被修改成true而已;若是線程的當前狀態處於阻塞狀態,那麼在將中斷標誌設置爲true後,還會有以下三種狀況之一的操做:

  • 若是是wait、sleep以及jion三個方法引發的阻塞,那麼會將線程的中斷標誌從新設置爲false,並拋出一個InterruptedException;
  • 若是是java.nio.channels.InterruptibleChannel進行的io操做引發的阻塞,則會對線程拋出一個ClosedByInterruptedException;(待驗證)
  • 若是是輪詢(java.nio.channels.Selectors)引發的線程阻塞,則當即返回,不會拋出異常。(待驗證)

    若是在中斷時,線程正處於非阻塞狀態,則將中斷標誌修改成true,而在此基礎上,一旦進入阻塞狀態,則按照阻塞狀態的狀況來進行處理;例如,一個線程在運行狀態中,其中斷標誌被設置爲true,則此後,一旦線程調用了wait、jion、sleep方法中的一種,立馬拋出一個InterruptedException,且中斷標誌被清除,從新設置爲false。

若是非阻塞---標誌位置爲true

若是阻塞-----標誌位也置爲true,而後還會繼續分好多狀況!若是是sleep引發的阻塞方式,則標誌位從新清除爲false!

若是這時候調用了interrupted函數,第一次返回true以後,再將標誌位置爲false!!而後第二第三次都是...false!

isInterrupted【外】]=false
thread.interrupt()....中斷==當前線程狀態==BLOCKED
isInterrupted【外】=true
interrupted【外】=false
interrupted【外】=false
執行線程體...
interrupted【內前】=true
進入睡眠...=RUNNABLE
結束線程...
interrupted【內後】=false
isInterrupted【外】]=false
thread.interrupt()....中斷==當前線程狀態==RUNNABLE
isInterrupted【外】=true
interrupted【外】=false
interrupted【外】=false
interrupted【內前】執行時,還沒被打斷=true
執行線程體...
進入睡眠...=RUNNABLE
結束線程...
interrupted【內後】=false
相關文章
相關標籤/搜索