2013年6月18日 星期二

Thread(1)

Thread:

一開始執行Thread,會有自己的stack記憶體,

儲存程式的區域變數。

main本身就為一個執行緒,

我們可以使用Thread.currentThread().getName()來取得執行緒的名稱。



public class Demo{

    public static void main(String[] args)
    {
     
     for( int i = 0 ; i < 30 ; i++ )
     {
      try{
       Thread.sleep(500);
       System.out.println("i: " + i  +"/ " + Thread.currentThread().getName() );
      }
      catch(Exception ex){
   
       System.out.println("err:" + ex );
   
      }
     }
    }

}



可以由此得到 thread的名稱為 main

接下來可以建立一個MyRunner的class,

去implement Runnable interface,

若不去implement的話,可以去extends Thread並override run()也是可以。



public class MyRunner implements Runnable{

 int i = 0;

 @Override
 public void run()
 {
  while(true)
  {
   try{
    Thread.sleep(500);
    System.out.println( "i:" + i++  + "/" + Thread.currentThread().getName() );

    if( i == 20 )
    {
     break;
    }
   }
   catch(Exception ex)
   {

   }
   

  }
 }
}



然後再建一個Demo.java去產生MyRunner的instance來進行測試。



public class Demo{

    public static void main(String[] args)
    {
     
     
        MyRunner r = new MyRunner();
        Thread t1 = new Thread(r);
        t1.run();
     
for( int i = 0 ; i < 30 ; i++ )
     {
      try{
       Thread.sleep(500);
       System.out.println("m: " + i  +"/ " + Thread.currentThread().getName() );
      }
      catch(Exception ex){
   
       System.out.println("err:" + ex );
   
      }
     }
    }

}



由這裡可以發現,我是用t1.run();來執行,

其實是故意的,從這個log我們可以看見

會先產生



i: 0/main
i: 1/main
i: 2/main
i: 3/main
    ‧


i: 19/main
m:0/main



m:29/main


上面的點點點就自己以此類推,

會發現居然thread的名稱都是main ,

因為我們用run()來跑,所以其實不是多建立一個thread,

他還是以main單執行緒來進行,

若要開一條新的thread的話,

我們要把

t1.run();  改成 t1.start();

再執行一次會發現變下面的log:



m: 0/ main
i:0/Thread-1
i:1/Thread-1
m: 1/ main
i:2/Thread-1
m: 2/ main
i:3/Thread-1
m: 3/ main
i:4/Thread-1
m: 4/ main
i:5/Thread-1
m: 5/ main
i:6/Thread-1
m: 6/ main
i:7/Thread-1
m: 7/ main
m: 8/ main
i:8/Thread-1
i:9/Thread-1
m: 9/ main
i:10/Thread-1
m: 10/ main
m: 11/ main
i:11/Thread-1
i:12/Thread-1



會發現thread的名稱多了一個Thread-1,

在開thread的預設名稱會以thread-編號,

當然我們可以自己定義Thread的名稱:

依上面的程式可以利用

t1.setName("自訂Thread名稱");

或用

Thread t1 = new Thread(r, "自訂Thread名稱");


接下來我們改變一下Demo.java


public class Demo{

    public static void main(String[] args)
    {
     
     
        MyRunner r = new MyRunner();
        Thread t1 = new Thread(r);
        Thread t2 = new Thread(r);
        t1.start();
        t2.start();
     
    }

}


可以發現log:



i:0/Thread-1
i:1/Thread-2
i:2/Thread-2
i:3/Thread-1
i:5/Thread-1
i:4/Thread-2
i:6/Thread-2
i:6/Thread-1
i:7/Thread-1
i:8/Thread-2
i:9/Thread-1
i:10/Thread-2
i:11/Thread-2
i:12/Thread-1
i:13/Thread-2
i:14/Thread-1
i:15/Thread-1
i:15/Thread-2
i:16/Thread-2
i:17/Thread-1
i:18/Thread-2
i:19/Thread-1



i的variable被共享了,所以在執行緒內的資源是可以共享的,

並且是Thread-safe。
☆轉載請註明出處

沒有留言: