Ex 111 Thread12 import java io import java

  • Slides: 38
Download presentation

程式 Ex 11_1 以Thread的子類別建立執行緒(1/2) import java. io. *; import java. lang. Math. *; /*

程式 Ex 11_1 以Thread的子類別建立執行緒(1/2) import java. io. *; import java. lang. Math. *; /* 建立Thread的子類別 */ class Counter_Thread extends Thread { private static int thread. Num=0; /* 類別變數thread. Num用來累計執行緒個數 */ private int current. Thread, loop. Limit; public Counter_Thread(int loop. Limit) /* 變數loop. Limit為計數值的上限 */ { this. loop. Limit = loop. Limit; current. Thread = thread. Num++; } private void pause(double seconds) /* 讓執行緒進入睡眠狀態 */ { try {Thread. sleep(Math. round(1000. 0*seconds)); } catch(Interrupted. Exception ie) {}; } public void run() /* 執行緒的執行由此開始 */ { for(int i=0; i<loop. Limit; i++) { System. out. println("Thread " + current. Thread + ": counter=" + i); pause(Math. random()); } // end for } } // end of Counter Java語言實務 7 執行緒

程式 Ex 11_1 以Thread的子類別建立執行緒(2/2) /* 測試執行緒 */ public class Counter { public static void

程式 Ex 11_1 以Thread的子類別建立執行緒(2/2) /* 測試執行緒 */ public class Counter { public static void main(String[] args) { /* 建立執行緒物件 */ Counter_Thread counter. Thread_1 = new Counter_Thread(8); Counter_Thread counter. Thread_2 = new Counter_Thread(8); counter. Thread_1. start();   /* 啟動執行緒 */ counter. Thread_2. start(); } // end main } // end Counter Java語言實務 8 執行緒

程式 Ex 11_1 可能的執行結果: Thread 0: counter=0 Thread 1: counter=0 Thread 0: counter=1 Thread

程式 Ex 11_1 可能的執行結果: Thread 0: counter=0 Thread 1: counter=0 Thread 0: counter=1 Thread 1: counter=2 Thread 1: counter=3 Thread 0: counter=2 Thread 1: counter=4 Thread 1: counter=5 Thread 1: counter=6 Thread 0: counter=3 Thread 0: counter=4 Thread 1: counter=7 Thread 0: counter=5 Thread 0: counter=6 Thread 0: counter=7 Java語言實務 9 執行緒

程式 Ex 11_2以定義Runnable界面建立執行緒 (1/2) import java. io. *; import java. lang. Math. *; /*

程式 Ex 11_2以定義Runnable界面建立執行緒 (1/2) import java. io. *; import java. lang. Math. *; /* 在類別中定義界面Runnable */ class Counter implements Runnable { private static int thread. Num=0; /* 類別變數thread. Num用來累計執行緒個數 */ private int current. Thread, loop. Limit; public Counter(int loop. Limit) /* 變數loop. Limit為計數值的上限 */ { this. loop. Limit = loop. Limit; current. Thread = thread. Num++; } private void pause(double seconds) /* 讓執行緒進入睡眠狀態 */ { try {Thread. sleep(Math. round(1000. 0*seconds)); } catch(Interrupted. Exception ie) {}; } public void run() /* 執行緒的執行由此開始 */ { for(int i=0; i<loop. Limit; i++) { System. out. println("Thread " + current. Thread + ": counter=" + i); pause(Math. random()); } // end for } // end run } // end Counter Java語言實務 10 執行緒

程式 Ex 11_2以定義Runnable界面建立執行緒 (2/2) /* 測試執行緒 */ public class Counter 2 { public static

程式 Ex 11_2以定義Runnable界面建立執行緒 (2/2) /* 測試執行緒 */ public class Counter 2 { public static void main(String[] args) { /* 建立執行緒物件 */ Thread counter. Thread_1 = new Thread(new Counter(8)); Thread counter. Thread_2 = new Thread(new Counter(8)); /* 啟動執行緒 */ counter. Thread_1. start(); counter. Thread_2. start(); } // end main } // end Counter 2 Java語言實務 11 執行緒

執行緒的生命週期 start born ready 取得執行權 讓出執行權 running Issue I/O request blocked stop suspend sleeping

執行緒的生命週期 start born ready 取得執行權 讓出執行權 running Issue I/O request blocked stop suspend sleeping dead wait suspendin g I/O completion Sleep interval expires resume waiting notify or notify. All ready Java語言實務 12 執行緒

程式 Ex 11_3 使用is. Alive()及join()範例(1/2) import java. io. *; import java. lang. Math. *;

程式 Ex 11_3 使用is. Alive()及join()範例(1/2) import java. io. *; import java. lang. Math. *; class Counter implements Runnable { private int loop. Limit; private String thread. Name; // name of thread Thread t; /* 變數t儲存執行緒物件的參考位址(reference) */ public Counter(int loop. Limit, String thread. Name) { this. loop. Limit = loop. Limit; this. thread. Name = thread. Name; /* 建立執行緒名稱為變數threadname的值 */ /* 保留字this指定該執行緒所要執行的程式片斷就在這個類別中定義 */ t = new Thread(this, thread. Name); t. start();        } private void pause(double seconds) { try {Thread. sleep(Math. round(1000. 0*seconds)); } catch(Interrupted. Exception ie) {}; } public void run() /* 執行緒的執行進入點 */ { for(int i=0; i<loop. Limit; i++) /* 列印迴圈控制變數I的值 */ { System. out. println("Thread: " + thread. Name + ": counter=" + i); pause(Math. random()); } // end for } // end run } // end Conter Java語言實務 13 執行緒

程式 Ex 11_3 使用is. Alive()及join()範例(2/2) public class Alive. Join { public static void main(String[]

程式 Ex 11_3 使用is. Alive()及join()範例(2/2) public class Alive. Join { public static void main(String[] args) { Counter c_1 = new Counter(2, "1");   Counter c_2 = new Counter(4, "2"); System. out. println("Thread 1 is alive: " + c_1. t. is. Alive()); System. out. println("Thread 2 is alive: " + c_2. t. is. Alive()); try { c_1. t. join(); /* 等待第一個執行緒結束 */ c_2. t. join(); /* 等待第二個執行緒結束 */ } catch (Interrupted. Exception e) {}   /* 此時二個執行緒皆已結束執行 */  System. out. println("Thread 1 is alive: " + c_1. t. is. Alive()); System. out. println("Thread 2 is alive: " + c_2. t. is. Alive()); } // end main } // end Alive. Join Java語言實務 14 執行緒

程式 Ex 11_3 可能的執行結果: Thread 1 is alive: true Thread 2 is alive: true

程式 Ex 11_3 可能的執行結果: Thread 1 is alive: true Thread 2 is alive: true Thread: 1: counter=0 Thread: 2: counter=0 Thread: 1: counter=1 Thread: 2: counter=2 Thread: 2: counter=3 Thread 1 is alive: false Thread 2 is alive: false Java語言實務 15 執行緒

程式 Ex 11. 4 使用suspend()及resume()方法範例 (1/2) (修改Ex 11_3的public class Alive. Join )以下述public class Resume.

程式 Ex 11. 4 使用suspend()及resume()方法範例 (1/2) (修改Ex 11_3的public class Alive. Join )以下述public class Resume. Suspend替代) public class Resume. Suspend { public static void main(String[] args) { Counter c_1 = new Counter(4, "1"); Counter c_2 = new Counter(4, "2"); c_2. t. suspend();  /* 暫停第二個執行緒的執行 */ System. out. println("Suspending Thread 2. " ); /* 藉由本方法的執行可確保在第一個執行緒結束後才會resume第二個執行緒 */ try {c_1. t. join(); } catch (Interrupted. Exception e) {} System. out. println("Thread 1 is alive: " + c_1. t. is. Alive()); System. out. println("Thread 2 is alive: " + c_2. t. is. Alive()); c_2. t. resume(); /* 恢復第二個執行緒的執行 */ System. out. println("Resuming Thread 2. " ); } // end main } // end Resume. Suspend Java語言實務 16 執行緒

執行之可能結果為: Thread: 1: counter=0 Thread: 2: counter=0 Suspending Thread 2. Thread: 1: counter=1 Thread:

執行之可能結果為: Thread: 1: counter=0 Thread: 2: counter=0 Suspending Thread 2. Thread: 1: counter=1 Thread: 1: counter=2 Thread: 1: counter=3 Thread 1 is alive: false Thread 2 is alive: true Resuming Thread 2. Thread: 2: counter=1 Thread: 2: counter=2 Thread: 2: counter=3 Java語言實務 17 執行緒

程式 Ex 11_5使用synchronized範例 (1/3) import java. io. *; class Number. Producer /* 模擬號碼產生機 */

程式 Ex 11_5使用synchronized範例 (1/3) import java. io. *; class Number. Producer /* 模擬號碼產生機 */ { int number=0;  /* 記錄目前可用號碼的變數 */ public Number. Producer(int initial. Value) { number = initial. Value; /* 將目前可用的號碼設定成initial. Value的值 */ } public int get. Number() /* 取得號碼並更新目前可用的號碼 */ { int num;        num = number; /* 休眠 1秒鐘讓其它的執行緒在完成取得號碼動作完成前獲得執行權*/ try { Thread. sleep(1000); } catch (Interrupted. Exception e) {}; number++;  /* 更新目前可用之號碼 */ return(num); /* 回傳取得之號碼 */ } } // end Number. Producer Java語言實務 19 執行緒

程式 Ex 11_5使用synchronized範例 (2/3) class Visitor extends Thread /* 模擬取號客戶 */ { int number; Number.

程式 Ex 11_5使用synchronized範例 (2/3) class Visitor extends Thread /* 模擬取號客戶 */ { int number; Number. Producer np;  /* 變數np存放客戶所使用的號碼機 */ public Visitor(Number. Producer np) { this. np= np; } public void run() { number = np. get. Number();  /* 領取號碼 */ } } // end Visitor Java語言實務 20 執行緒

程式 Ex 11_5使用synchronized範例 (3/3) public class Num. Machine { public static void main(String[] args)

程式 Ex 11_5使用synchronized範例 (3/3) public class Num. Machine { public static void main(String[] args) { Number. Producer np; Visitor v 0, v 1, v 2, v 3; np = new Number. Producer(1);  /* 產生號碼機物件 */ v 0 = new Visitor(np);  /* 建立執行緒模擬四位先後到達的客戶及取號 */ v 0. start(); v 1 = new Visitor(np); v 1. start(); v 2 = new Visitor(np); v 2. start(); v 3 = new Visitor(np); v 3. start(); try { v 0. join(); v 1. join(); v 2. join(); v 3. join(); /* 等待上述四個執行緒執行結束 */ } catch (Interrupted. Exception e) {};   /* 列印取得的號碼 */ System. out. println("Visitor 0: Number: " + v 0. number); System. out. println("Visitor 1: Number: " + v 1. number); System. out. println("Visitor 2: Number: " + v 2. number); System. out. println("Visitor 3: Number: " + v 3. number); } // end main } // end Num. Machine Java語言實務 21 執行緒

程式 Ex 11_6 wait()及notify()使用範例 (1/5) import java. io. *; class Number. Queue /* 模擬號碼產生器中存放及更新號碼的類別 */

程式 Ex 11_6 wait()及notify()使用範例 (1/5) import java. io. *; class Number. Queue /* 模擬號碼產生器中存放及更新號碼的類別 */ { int number=0; /* 存放所產生的號碼 */ boolean ticken. Taken=true;  /* 記錄號號否已被取走 */ public Number. Queue(int initial. Value) { number = initial. Value;  /* 設定號碼初值為initial. Value變數的值 */ } public synchronized int get. Number() { if (ticken. Taken)  /* 如果號碼已被取走則等待新號碼產生後後才繼續執行 */ try { wait(); }catch(Interrupted. Exception e){}; ticken. Taken=true; /* 設定號碼已被取走 */ notify();  /* 告知佇列中第一個執行緒可以進入ready狀態以便恢復執行 */ return(number); /* 傳回取得的號碼 */ } Java語言實務 24 執行緒

程式 Ex 11_6 wait()及notify()使用範例 (3/5) class Consumer extends Thread /* 取得號碼的執行緒 */ { int ticket.

程式 Ex 11_6 wait()及notify()使用範例 (3/5) class Consumer extends Thread /* 取得號碼的執行緒 */ { int ticket. Number; Number. Queue nq; public Consumer(Number. Queue nq)  { this. nq = nq; } public void run() { ticket. Number = nq. get. Number();  /* 取得一個號碼 */ } } // end of Consumer class Producer extends Thread /* 設定新號碼的執行緒 */ { Number. Queue nq; public Producer(Number. Queue nq) { this. nq = nq; } public void run() { while (true) nq. set. Number();  /* 設定新的號碼 */ } } // end of Producer Java語言實務 26 執行緒

程式 Ex 11_6 wait()及notify()使用範例 (4/5) public class Num. Machine 2 { public static void

程式 Ex 11_6 wait()及notify()使用範例 (4/5) public class Num. Machine 2 { public static void main(String[] args) { Number. Queue nq; /* 變數nq用來存放號碼產生器的參考 */  Consumer c 0, c 1, c 2, c 3; Producer p 0; nq = new Number. Queue(0);   /* 建立號碼產生器 */ p 0 = new Producer(nq);   /* 建立設定新號碼的執行緒 */ p 0. start(); c 0 = new Consumer(nq); /* 建立第一個取得號碼的執行緒 */ c 0. start(); try {c 0. join(); } catch (Interrupted. Exception e) {};  /* 等待第一個執行緒執行結束 */ c 1 = new Consumer(nq);   /* 建立第二個取得號碼的執行緒 */ c 1. start(); try { c 1. join(); } catch (Interrupted. Exception e) {};  /* 等待第二個執行緒執行結束 */ c 2 = new Consumer(nq); c 2. start(); try {c 2. join(); } catch (Interrupted. Exception e) {}; c 3 = new Consumer(nq); c 3. start(); try {c 3. join(); } catch (Interrupted. Exception e) {}; Java語言實務 27 執行緒

程式 Ex 11_6 wait()及notify()使用範例 (5/5)  /* 列印各執行緒取得的號碼 */ System. out. println("Consumer 0: Ticket Number:

程式 Ex 11_6 wait()及notify()使用範例 (5/5)  /* 列印各執行緒取得的號碼 */ System. out. println("Consumer 0: Ticket Number: " + c 0. ticket. Number); System. out. println("Consumer 1: Ticket Number: " + c 1. ticket. Number); System. out. println("Consumer 2: Ticket Number: " + c 2. ticket. Number); System. out. println("Consumer 3: Ticket Number: " + c 3. ticket. Number); System. out. println("Press ctrl+c to stop!"); } // end of main } // end of Num. Machine 2 執行結果: Consumer 0: Ticket Number: 1 Consumer 1: Ticket Number: 2 Consumer 2: Ticket Number: 3 Consumer 3: Ticket Number: 4 Press ctrl+c to stop! Java語言實務 28 執行緒

程式 Ex 11. 7 設定執行緒優先權範例(2/3) public class Priority { public static void main(String[] args)

程式 Ex 11. 7 設定執行緒優先權範例(2/3) public class Priority { public static void main(String[] args) { Accumulator a 1, a 2;   /* 將主執行緒的優先權設為最高 */ Thread. current. Thread(). set. Priority(Thread. MAX_PRIORITY); a 1 = new Accumulator(0);   /* 建立計算累加值的執行緒 */ a 2 = new Accumulator(0); a 1. set. Priority(Thread. NORM_PRIORITY-3);   /* 設定執行緒的優先權值 */ a 2. set. Priority(Thread. NORM_PRIORITY+3); a 1. set. Name("Accumulator_a 1");  /* 設定執行緒的名稱 */ a 2. set. Name("Accumulator_a 2"); a 1. start();  /* 啟動執行緒 */ a 2. start(); try {Thread. sleep(1000); }  /* 主執行緒進入休眠狀態 */ catch(Interrupted. Exception e){} Java語言實務 31 執行緒

程式 Ex 11. 7 設定執行緒優先權範例(3/3) a 1. running = false;   /* 設定running值以便結束執行緒的累加運算 */

程式 Ex 11. 7 設定執行緒優先權範例(3/3) a 1. running = false;   /* 設定running值以便結束執行緒的累加運算 */ a 2. running = false; try { a 1. join();  /* 等待執行緒結束 */ a 2. join(); } catch (Interrupted. Exception e) {}; /* 列印累加結果及相關資訊 */ System. out. println("[Main Thread name: " + Thread. current. Thread(). get. Name() + " Priority: " + Thread. current. Thread(). get. Priority() + "]"); System. out. println("Accumulator a 1: sum = " + a 1. sum + " [Thread Name: " + a 1. get. Name() + " Priority: " + a 1. get. Priority() + "]"); System. out. println("Accumulator a 2: sum = " + a 2. sum + " [Thread Name: " + a 2. get. Name() + " Priority: " + a 2. get. Priority()+"]"); } // end of main } // end of Priority Java語言實務 32 執行緒

執行可能結果: [Main Thread name: main Priority: 10] Accumulator a 1: sum = 0 [Thread

執行可能結果: [Main Thread name: main Priority: 10] Accumulator a 1: sum = 0 [Thread Name: Accumulator_a 1 Priority: 2] Accumulator a 2: sum = 96801653 [Thread Name: Accumulator_a 2 Priority: 8] 由於「執行緒」Accumulator_a 1的優先權值為 2,這使得一 直到程式結束執行時,Accumulator_a 1可能仍無法取得執 行權,因此Accumulator_a 1的累加值sum為 0。 Java語言實務 33 執行緒

程式 Ex 11_8 執行緒群組使用範例(1/3) import java. io. *; class Accumulator extends Thread /* 宣告執行緒類別 */

程式 Ex 11_8 執行緒群組使用範例(1/3) import java. io. *; class Accumulator extends Thread /* 宣告執行緒類別 */ { int sum; /* 記錄累加值的變數 */ boolean running = true; Accumulator (Thread. Group group, String thread. Name, int init. Value) /* 建構子 */ { /* 呼叫上層建構子,建立隸屬於群組gorup名稱為thread. Name的執行緒 */ super(group, thread. Name); this. sum = init. Value; /* 設定累加變數的初值 */ } public void run() /* 執行緒的執行進入點 */ { while(running) sum = sum + 1; } } // end of Accumulator Java語言實務 35 執行緒

程式 Ex 11_8 執行緒群組使用範例(2/3) public class TGroup { public static void main(String[] args) {

程式 Ex 11_8 執行緒群組使用範例(2/3) public class TGroup { public static void main(String[] args) { Accumulator a 1, a 2; Thread. Group group; group = new Thread. Group("Accumulator_Group"); /* 建立執行緒群組 */ a 1 = new Accumulator(group, "Accumulator_a 1", 0); /* 建立計算累加值的執行緒 */ a 2 = new Accumulator(group, "Accumulator_a 2", 0); /* 將主執行緒的優先權設為最高 */ Thread. current. Thread(). set. Priority(Thread. MAX_PRIORITY); a 1. set. Priority(Thread. NORM_PRIORITY-3); /* 設定執行緒的優先權值 */ a 2. set. Priority(Thread. NORM_PRIORITY+3); a 1. start();  /* 啟動執行緒(亦可透過執行緒群組的start()方法同時啟動a 1及a 2)*/ a 2. start(); Java語言實務 36 執行緒

程式 Ex 11_8 執行緒群組使用範例(3/3) try {Thread. sleep(1000); } /* 主執行緒進入休眠狀態 */ catch(Interrupted. Exception e){}

程式 Ex 11_8 執行緒群組使用範例(3/3) try {Thread. sleep(1000); } /* 主執行緒進入休眠狀態 */ catch(Interrupted. Exception e){} group. stop(); /* 結束執行緒群組內所有執行緒的執行 */ try { a 1. join();  /* 等待執緒行結束 */ a 2. join(); } catch (Interrupted. Exception e) {}; /* 列印執行緒群組相關資訊 */ System. out. println("[Thread Group Name: "+group. get. Name()+ ", Max Priority: "+group. get. Max. Priority()+"]"); /* 列印累加結果 */ System. out. println("Accumulator a 1: sum = "+a 1. sum); System. out. println("Accumulator a 2: sum = "+a 2. sum ); } // end of main } // end of TGroup Java語言實務 37 執行緒

執行可能結果: [Thread Group Name: Accumulator_Group, Max Priority: 10] Accumulator a 1: sum = 0

執行可能結果: [Thread Group Name: Accumulator_Group, Max Priority: 10] Accumulator a 1: sum = 0 Accumulator a 2: sum = 160567022 Java語言實務 38 執行緒