JAVA線程(二)

這篇文章不想說的太深入,因爲筆者也不敢說很懂JAVA Thread的使用,但是通過以下幾個常用的例子和說明,筆者希望能夠向大家展示下JAVA Thread的一些常見用法(以下是我整理的一些資料和一些自己寫的示例程序)。

1.如何終止一個線程

終止線程有三種方法

    有三種方法可以使終止線程。

    1.  使用退出標誌,使線程正常退出,也就是當run方法完成後線程終止。
    2.  使用stop方法強行終止線程(這個方法不推薦使用,因爲stop和suspend、resume一樣,也可能發生不可預料的  結果)。 不推薦
    3.  使用interrupt方法中斷線程。推薦

    第一種方法終止線程(使用退出標誌,看註釋就好,註釋寫的很清楚了)

public class TestThread extends Thread{  
        //鎖住exit,保證當前只有一個線程能夠訪問並修改exit變量  
        //通過設置這個標誌來控制while循環是否退出  
        public volatile boolean exit = false;  
          
        public void run(){  
            while(!exit);  
            System.out.println("跳出循環了!");  
        }  
          
        public static void main(String[] args) throws Exception{  
            TestThread thread = new TestThread();  
            thread.start();  
              
            sleep(5000);//使當前線程延遲5秒後啓動(主線程)  
            thread.exit = true;//更改exit跳出while循環  
            thread.join();//讓調用該方法的thread完成run方法裏面的內容後,在執行join()方法後面的東西  
            System.out.println("線程退出!");  
        }  
    }
第二種方法終止線程

   使用stop方法可以強行終止正在運行或掛起的線程。我們可以使用如下的代碼來終止線程

thread.stop();

雖然使用上面的代碼可以終止線程,但使用stop方法是很危險的,就象突然關閉計算機電源,而不是按正常程序關機一樣,可能會產生不可預料的結果,因此,並不推薦使用stop方法來終止線程。(雖然筆者目前還沒有深入研究爲什麼可能會產生不可預料的結果,但是這裏希望大家有這個意識,不要使用這種方式強行終止一個線程,當然,具體原因有興趣的朋友可以再仔細閱讀JDK相關文檔)


第三種方法終止線程

   使用interrupt方法終止線程

  (1)線程處於阻塞狀態,如使用了sleep方法。
  (2)使用while(!isInterrupted()){……}來判斷線程是否被中斷。


第一種情況(看註釋,註釋寫得很清楚了):

public class ThreadInterrupt extends Thread{  
      
        @Override  
        public void run() {  
            try {  
                sleep(50000);//該線程延遲50秒後執行  
            } catch (InterruptedException e) {  
                System.out.println(this.isInterrupted() + " " + e.getMessage());  
            }  
        }  
          
        public static void main(String[] args) throws Exception{  
            Thread thread = new ThreadInterrupt();  
            thread.start();  
            System.out.println(thread.isInterrupted());  
              
            System.in.read();//隨意輸入一些內容  
            thread.interrupt();//調用interrupt方法,使得sleep方法拋出一個interruptedException例外  
            System.out.println(thread.isInterrupted());//在異常尚未捕捉到時,看一下這個interrupted這個變量的值  
            thread.join();//使調用這個join的thread執行完run方法後,再執行後面的內容  
              
            System.out.println("線程已經退出");  
        }  
          
    }  

我們看到,當線程調用interrupt方法後,檢測到的isInterrupted()方法的值爲true,但是捕獲到這個異常後isInterrupted()已經被重新置爲false了,即線程的狀態變爲非中斷狀態,那麼如果你的run中是一個循環的話,那麼如果catch語句沒有處理異常,則下一 次循環中isInterrupted()爲false,線程會繼續執行,可能你N次拋出異常,也無法讓線程停止,如下面的例子:

我們看到這裏,只是捕獲了異常,而沒有做相應的處理,導致線程仍舊再執行,如下:

我們看到這裏,只是捕獲了異常,而沒有做相應的處理,導致線程仍舊再執行,如下:


因此,我們可以使用一種叫做“二次惰性檢測(double check)”的方式,能在提高效率的基礎上又確保線程真正中同步控制中,即不以isInterrupted ()爲循環條件。而以一個標記作爲循環條件,如下:

public class ThreadB extends Thread{
	   private boolean isInterrupted=false;
	   int count=0;
	   
	   public void interrupt(){
	       isInterrupted = true;
	       super.interrupt();
	      }
	   
	   public void run(){
	       System.out.println(getName()+"將要運行...");
	       while(!isInterrupted){
	           System.out.println(getName()+"運行中"+count++);
	           try{
	               Thread.sleep(400);
	           }catch(InterruptedException e){
	               System.out.println(getName()+"從阻塞中退出...");
	               System.out.println("this.isInterrupted()="+this.isInterrupted());

	           }
	       }
	       System.out.println(getName()+"已經終止!");
	   }
	   
	   public static void main(String[] args) throws Exception{
	        ThreadB tb=new ThreadB();
	        tb.setName("Thread b");
	        tb.start();
	        sleep(2000);
	        System.out.println(tb.getName()+"正在被中斷...");
	        tb.interrupt();
	        System.out.println("tb.isInterrupted()="+tb.isInterrupted());
	   }
}

輸出如下:


在這第二篇有關JAVA線程的內容,我就先說這麼多,也希望,無論是我寫的有問題還是對這裏的內容有疑惑,都希望大家提出來!


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章