線程的建立終止和生命週期

1 線程的建立html

 

方法1:實現Runnable接口(推薦)java

class Runner1 implements Runnable {
    public void run() {
        for(int i=0; i<30; i++) System.out.println("No. " + i);
    }
}
public class TestThread1 {
    public static void main(String args[]) {
        Thread t1 = new Thread(new Runner1());
        t1.start();
    }
}

Runable是任務的概念,若是咱們直接這樣寫,會怎麼樣呢?只會在原來的線程(Main的)裏執行run方法。可見Runable更靈活,任務不用寫死在線程裏,能夠放到不一樣的線程,甚至線程池裏運行。把任務和運行分離api

public class TestThread1 {
    public static void main(String args[]) {
        Runnable r1 = new Runner1();
        r1.run();
    }
}

 

方法2:繼承Threadspa

class Thread1 extends Thread {
    public void run() {
        for(int i=0; i<100; i++) {    
            System.out.println("Runner1 :" + i);
        }
    }
}
public class TestThread1 {
    public static void main(String args[]) {
        Thread1 t1 = new Thread1();
        t1.start();
    }
}

 

2 線程的終止線程

參考:http://www.cnblogs.com/skywang12345/p/3479949.htmlcode

http://hapinwater.iteye.com/blog/310558htm

  線程的終止主要有三種方式:blog

  a. interrupt;繼承

  b. 經過額外標識位;接口

  c. suspend(暫停),resume(恢復),stop(終止),這三個方法已通過時。suspend和resume就像唱片機,能停能恢復,如今主要被wait/notify取代。stop終止線程太暴力,沒時間讓線程釋放資源,因此被淘汰了。

  這些終止是讓別的線程終止本身,因別人啓動,因別人終止啊~。要終止本身只要從run方法return就行。

2.1 interrupt

每一個線程上都有一個標識位interrupted,說明該線程是否被中斷。當interrupt()時,只會改標誌位,不會真的終止線程。我這裏加了一個on標識來關掉這個線程,不然咱們就沒辦法關閉它了。

class ATask  extends Thread { 
    private volatile boolean on=true;
    
    public void run() {
        while (on) {  
            System.out.println("I am running!");                
            for (int i = 0; i < 10000000; i++);
        }  
    }
    
    public void shutdown(){
        on=false;
    }
}  
  
public class TestThread {  
      
    public static void main(String[] args) throws Exception{
        ATask t = new ATask();  
        t.start();  
          
        //運行一斷時間中斷線程  
        Thread.sleep(20);  
        System.out.println("****************************");  
        System.out.println("Interrupted Thread!");  
        System.out.println("****************************");  
        t.interrupt();
        Thread.sleep(20);
        System.out.println("ShutDown Thread!");  
        System.out.println("****************************");  
        t.shutdown();
    }  
}   

運行結果:

I am running!
I am running!
****************************
Interrupted Thread!
****************************
I am running!
I am running!
ShutDown Thread!
****************************

  interrupted能夠經過myThread.isInterrupted()查詢,也能夠經過Thread.interrupted()重置interrupted標誌位(設爲fasle)。

  java給了線程編寫者自由,讓他定義在別人中斷本身時怎麼響應。主要分兩種狀況,一種是阻塞式的,另外一種是非阻塞式。

a. 阻塞式的:調用了sleep(), wait(), join()等方法就會進入阻塞狀態。就是說幹什麼已經不禁線程編寫者決定,控制權交到sleep裏。這些阻塞方法都會拋InterruptedException異常,我麼只要在catch裏響應Interrupt。能夠向下面乖乖地return,就終止了線程(並釋放相應資源);也能夠直接無論(catch裏什麼都不寫),這樣線程就會繼續while下去。這裏有個小細節,在拋InterruptedException時,虛擬機會重置interrupted標誌位。

class ATask  extends Thread { 
    public void run() {
        while(true){            
            try {
                System.out.println("I am running!");
                sleep(1000);
            } catch (InterruptedException e) {
                System.out.println("ATask.run() interrupted!");
                return;
            }
        }       
    }  
} 


public class TestThread {
    public static void main(String[] args) throws Exception{  
        //將任務交給一個線程執行  
        Thread t = new ATask();  
        t.start();  
          
        //運行一斷時間中斷線程  
        Thread.sleep(20);  
        System.out.println("****************************");  
        System.out.println("Interrupted Thread!");  
        System.out.println("****************************");  
        t.interrupt();  
    }
}

運行結果:

I am running!
****************************
Interrupted Thread!
****************************
ATask.run() interrupted!

 

b. 非阻塞式方法:不是阻塞式的,控制權在本身手裏。

class ATask  extends Thread { 
    public void run() {  
        //檢查程序是否發生中斷  
        while (!Thread.interrupted()) {  
            System.out.println("I am running!");
            for (int i = 0; i < 1000000; i++); 
        }
        System.out.println("ATask.run() interrupted!");  
    }  
} 
public class TestThread{  
    
    public static void main(String[] args) throws Exception{  
        //將任務交給一個線程執行  
        Thread t = new ATask();  
        t.start();  
          
        //運行一斷時間中斷線程  
        Thread.sleep(20);  
        System.out.println("****************************");  
        System.out.println("Interrupted Thread!");  
        System.out.println("****************************");  
        t.interrupt();  
    }  
} 

運行結果:

I am running!
I am running!
****************************
Interrupted Thread!
****************************
ATask.run() interrupted!

 

2.2 經過額外標識位

class ATask  extends Thread {
    private volatile boolean on = true;
    
    public void run() {
        while(on){            
             System.out.println("I am running!");                
             for (int i = 0; i < 10000000; i++);
        }
    }
    
    public void shutDown() {
        on = false;
    }
} 

public class TestThread {
    public static void main(String[] args) throws InterruptedException{  
        //將任務交給一個線程執行  
        ATask t = new ATask();  
        t.start();  
          
        //運行一斷時間中斷線程  
        Thread.sleep(20);  
        System.out.println("****************************");  
        System.out.println("shutDown Thread!");  
        System.out.println("****************************");  
        t.shutDown();  
    }
}

對比2.1,2.2兩種方法:

a 都能 自由地處理其餘線程的終止請求;

b 都能 在終止時釋放資源;

c 2.2不能終止處於阻塞狀態的線程。

 

3 線程的生命週期

 線程的狀態起始很簡單,就是啓動->運行->終止。等待,超時等待,阻塞都是一種阻塞狀態,到用到時在分析,和線程的狀態沒太多關係,就那麼簡單。

相關文章
相關標籤/搜索