Multithreading

asia_university_multiThread

單執行緒

在 CTest class 裡面寫 run 的執行緒
在 main 裡面呼叫 CTest物件的 run

class CTest{ private String id; public CTest(String str){ id = str; } public void run(){ for(int i=0 ; i<4 ;i++){ for(int j=0 ; j<100000000 ; j++); System.out.println(id+" is running..."); } } } public class app15_1{ public static void main(String args[]){ CTest dog = new CTest("doggy"); CTest cat = new CTest("kitty"); dog.run(); cat.run(); } }

啟動執行緒

兩個執行緒

CTest2 extends Thread
new CTest2物件.start()
Thread 讓 CTest 開始時會跑 run

class CTest2 extends Thread { private String id; public CTest2(String str){ id = str; } public void run(){ for(int i=0 ; i<4 ;i++){ for(int j=0 ; j<100000000 ; j++); System.out.println(id+" is running..."); } } } public class app15_2{ public static void main(String args[]){ CTest2 dog = new CTest2("doggy"); CTest2 cat = new CTest2("kitty"); dog.start(); cat.start(); } } /* 從 Thread 類別 延伸出子類別 CTest */ /* 呼叫 start() method 時,會在排成器中登錄該程序,當它開始執行時,run() method自然會被呼叫*/

建立執行緒

兩個執行緒

如果類別本身已經繼承某個父類別
可以利用實作 Runnable 介面 的方式建立執行緒

  • 介面 是實現多重繼承 的重要方式
  • 把處理執行緒的程式碼,放在實作 Runnable 介面的類別中的run() 就可以建立執行緒
// 由 Ctest3 類別 實作 Runnable 介面 class CTest3 implements Runnable { private String id; public CTest3(String str) { id = str; } public void run() { // 執行緒,等、印 for(int i=0; i<4; i++){ for(int j=0; j<10000000; j++); System.out.println( id+" is running.." ); } } } public class app15_3 { public static void main(String args[]){ CTest3 dog = new CTest3("doggy"); CTest3 cat = new CTest3("kitty"); Thread t1 = new Thread(dog); Thread t2 = new Thread(cat); t1.start(); t2.start(); } } // Thread(CTest3物件的名稱) // 產生 Thread 類別的物件 t1 // 用 Thread 類別的物件 t1.start

執行緒的產生和銷毀

  • newly created
    • start()
      • runable
  • runable
    • wait()
    • sleep()
      • blocked
    • run()
      • daed
  • blocked
    • notify()
    • sleep()
      • runable
  • dead

newly created

  • new Thread
  • start() method
    • 執行緒啟動,CPU配置資源,執行緒搶資源

runable

  • start() method
    • 啟動後,就是狀態:可執行
    • 搶到資源後,run()
      • 其他執行緒在 queue 中等待資源

blocked

執行緒不執行

    1. wait()
    1. sleep()
    1. 執行緒和另一個執行緒join()

blocked dismiss

  1. 如果執行緒是由呼叫物件的 wait() method 所凍結,則該物件的 notify() method 被呼叫時可解除凍結
  2. 執行緒sleep(),但時間已到

dead

  • run() 後
    • 執行緒呼叫自己的 stop() ,狀態:銷毀


sleep

class CTest4 extends Thread{ private String id; public CTest4 (String str){ id = str; } public void run(){ for(int i=0;i<3;i++){ try{ int sec = (int)(1000*Math.random()); sleep(sec); System.out.println(String.valueOf(sec)+" "+id); } catch(InterruptedException e){} System.out.println(" "+id+" is running.."); } } } /* * Math.random() 會產生 0~1 之間的亂數, * 乘上 1000 後,變成 0~1000 之間的浮點數亂數, * 再強制轉換成整數, * 控制執行緒的小睡時間為 0秒 到 1秒 之間的亂數 * */ public class app15_4{ public static void main(String args[]){ CTest4 dog = new CTest4("doggy"); CTest4 cat = new CTest4("kitty"); dog.start(); cat.start(); } } /* * * */

通常會先執行不須啟動執行緒的程式

main() method 本身也是一個執行緒,通常system.out.println()會先執行,因為會先執行不須啟動執行緒的程式。

class CTest4 extends Thread{ private String id; public CTest4 (String str){ id = str; } public void run(){ for(int i=0;i<3;i++){ System.out.println(" "+id+" is running.."); } } } public class app15_5{ public static void main(String args[]){ CTest4 dog = new CTest4("doggy"); CTest4 cat = new CTest4("kitty"); dog.start(); cat.start(); System.out.println(" main() here"); } }

join

執行緒.join() => 先執行