1. 程式人生 > >開始一個執行緒兩種方式的區別

開始一個執行緒兩種方式的區別

java 開始一個現成有兩中方法 :一是直接呼叫Thread例項的start()方法,二是將Runable例項傳給一個Thread例項然後呼叫它的start()方法。

首先讓我們看看Thread類的start() 方法:

public synchronized void start() {
        if (started)
            throw new IllegalThreadStateException();
        started = true;
        group.add(this);
        start0();
    }
一個Thread的例項一旦呼叫了start() 方法,這個例項的started標記就標記為true,不管這個執行緒是否給執行,只要呼叫了一次start()就再也沒有機會運行了.這意味著:通過Thread的start() 方法,一個Thread只能生成一個執行緒.所以下面的程式碼會丟擲異常:

public class Test {
  public static void main(String[] args) throws Exception{
    MyThread mt = new MyThread();
    mt.start();
    mt.join();//線上程物件a上呼叫join()方法,就是讓當前正在執行的執行緒等待執行緒物件a對應的執行緒執行完成後才繼續執行
    Thread.sleep(3000);
    mt.start();
  }
}

  當執行緒物件mt執行完成後,我們讓主執行緒休息一下,然後我們再次在這個執行緒物件上啟動執行緒。結果我們看到:

  Exception in thread "main" java.lang.IllegalThreadStateException

如果要讓一個例項產生多個執行緒,著就要使用Runnable 藉口的功能了.

如果我們把一個Runnable例項給Thread物件多次包裝,我們就可以看到它們實際是在同一例項上啟動執行緒:

class R implements Runnable{
  private int x = 0;
  public void run(){

    for(int i=0;i<100;i++){
      try{
        Thread.sleep(10);
      }catch(Exception e){}
      System.out.println(x++);

    }
  }
}
public class Test {
  public static void main(String[] args) throws Exception{
    R r = new R();
    for(int i=0;i<10;i++)
      new Thread(r).start();
  }
}
x 是例項變數,但結果是x被加到了999,說明這10個執行緒是在同一個r物件上執行的.

但是如果使用Thread 來使用執行緒:

class MyThread extends Thread{
  public int x = 0;
 
  public void run(){
   
    for(int i=0;i<100;i++){
      try{
        Thread.sleep(10);
      }catch(Exception e){}
      System.out.println(x++);
     
    }
  }
}

public class Test {
  public static void main(String[] args) throws Exception{
       for(int i=0;i<10;i++)
      new  MyThread  ().start();

}
}
x例項變數被建立了10次,每個現程建立了一次,每個x都是加到了10.不像Runnable 物件,每個現成都共享同一個Runnable 物件,共享同一個例項變x.

我們把上面用Runnable 方式建立的執行緒,同一例項(Runnable例項)的多個執行緒

從dev2dev網友axman的go deep into java專欄文件,結合自己的總結而來.