讓你的程式具有「多工」 及「平行處理」的能力

Slides:



Advertisements
Similar presentations
作者 : 陳鍾誠 單位 : 金門技術學院資管系 URL : 日期 : 2016/7/21 行程的同步 註:本章學術性較重,但考試常考。
Advertisements

软件编程基础 一、程序的编辑 Java 源程序是以 Java 为后缀的简单的文本文件,可以用各种 Java 集成开发环境中的源代码编辑器来编写,也可以用其他文 本编辑工具,如 Windows 中的记事本或 DOS 中的 EDIT 软件等。 利用文字编辑器编写下列程序 public class Hello.
Java 程序分类 Java Application :是完整程序,需要独立的解 释器解释运行;以 “.java” 为后缀的文件,以 main() 方法作为程序入口,由 java 编译器编译生 成字节码,由 Java 解释器加载执行字节码。 Java Applet 没有 main() 方法作为程序入口,是嵌在.
第四章 类、对象和接口.
第三讲 面向对象(上).
3.2 Java的类 Java 类库的概念 语言规则——程序的书写规范 Java语言 类库——已有的有特定功能的Java程序模块
第一單元 建立java 程式.
项目6 通用堆栈.
讓你的程式具有多工(Multitasking) 及多重處理(Multiprocessing)的能力
四資二甲 第三週作業 物件導向程式設計.
算法设计与分析 Algorithm Design and Analysis
第11章 Java多媒体技术.
第二章 JAVA语言基础.
Chapter 5 迴圈.
程式設計實作.
2.1 基本資料型別 2.2 變數 2.3 運算式與運算子 2.4 輸出與輸入資料 2.5 資料型別轉換 2.6 實例
例外處理(Exception Handling)
JAVA vs. SQL Server 建國科技大學 資管系 饒瑞佶 2013/4 V1.
Applied Operating System Concepts
Java语言程序设计 第七部分 多线程.
Java基础 JavaSE异常.
Multithread 多執行緒 I/O Lecturer:楊昌樺.
C#程序设计 c# programming 多线程 C#程序设计课程组.
程式設計實作.
程式撰寫流程.
2018/12/3 面向对象与多线程综合实验-网络编程 教师:段鹏飞.
類別(class) 類別class與物件object.
SQL Stored Procedure SQL 預存程序.
第9章 多线程 王德俊 上海交通大学继续教育学院.
Ch13 執行緒(I) 物件導向系統實務.
第三章 流程控制與例外處理 資訊教育研究室 製作 注意:本投影片僅供上課使用,非經同意,請勿散播或轉載。
第10章 Java的线程处理 10.1 线程的基本概念 10.2 线程的属性 10.3 线程组 10.4 多线程程序的开发.
第一次课后作业 1. C/C++/Java 哪些值不是头等程序对象 2. C/C++/Java 哪些机制采用的是动态束定
精彩Java 2程式設計 <吳逸賢、吳目誠 編著>
9.1 程式偵錯 9.2 捕捉例外 9.3 自行拋出例外 9.4 自定例外類別 9.5 多執行緒
Java 程式設計 講師:FrankLin.
$16 进程和线程. $16 进程和线程 进程 进程 属性 ProcessName / Id MachineName / MainModule BasePriority StartTime / ExitTime TotalProcessorTime / UserProcessorTime PrivateMemorySize64.
异常及处理.
JAVA 程式設計與資料結構 第四章 陣列、字串與數學物件.
C/C++/Java 哪些值不是头等程序对象
第一單元 建立java 程式.
4.2通讯服务模块线程之间传递信息 信息工程系 向模军 Tel: QQ:
Ch20. 計算器 (Mac 版本).
Multithread 多執行緒 以GUI為例了解物件以及Event
JAVA 编 程 技 术 主编 贾振华 2010年1月.
《JAVA程序设计》 语音答疑 辅导老师:高旻.
第 19 章 XML記憶體執行模式.
第二章Java基本程序设计.
第7章 异常处理.
第二章 Java基本语法 讲师:复凡.
Java程式初體驗大綱 大綱 在學程式之前及本書常用名詞解釋 Hello Java!程式 在Dos下編譯、執行程式
第二章 Java语法基础.
第二章 Java基本语法 讲师:复凡.
第二章 Java基本语法 讲师:复凡.
第四章 陣列、指標與參考 4-1 物件陣列 4-2 使用物件指標 4-3 this指標 4-4 new 與 delete
Activity的生命週期: 播放音樂與影片 靜宜大學資管系 楊子青
PPT注意事项: 当前PPT课件文件必须和提供的源代码文件夹“代码”在同一目录中即不要移动文件夹“代码”的默认位置。
JAVA 程式設計與資料結構 第三章 物件的設計.
第2章 Java语言基础.
迴圈(重複性結構) for while do while.
判斷(選擇性敘述) if if else else if 條件運算子.
ABAP Basic Concept (2) 運算子 控制式與迴圈 Subroutines Event Block
SQLite資料庫 靜宜大學資管系 楊子青.
Chapter 4 Multi-Threads (多執行緒).
第二章 Java基础语法 北京传智播客教育
輸出執行結果到螢幕上 如果要將執行結果的文字和數值都「輸出」到電腦螢幕時,程式要怎麼寫? class 類別名稱 {
第二章 Java基本语法 讲师:复凡.
方法(Method) 函數.
ABAP Basic Concept (2) 運算子 控制式與迴圈 Subroutines Event Block
InputStreamReader Console Scanner
Presentation transcript:

讓你的程式具有「多工」 及「平行處理」的能力 執行緒 Thread 讓你的程式具有「多工」 及「平行處理」的能力

本章重點 什麼是「執行緒」 執行緒的程式架構 執行緒的生命週期 執行緒的同步協調 執行緒優先權的管理 「執行緒群組」的管理 Java語言實務

什麼是「執行緒」 支援「平行處理」的執行控制機制,它可以執行程式中任何一組相關且可與程式中其它部分「平行處理」的程式片斷。 播放背景音樂 執行緒a: 數數運算 執行緒c: 動畫顯示 執行緒b: 程式(多執行緒) Java語言實務 執行緒

「執行緒」具有以下幾個基本特徵: 不是完整的程式。 隸屬於同一個程式的「執行緒」必需共享系統分配給所屬主程式的資源(如記憶體空間、CPU時間等)。 每一個「執行緒」都有自己的「執行堆疊」及「程式計數器」 程式可以設定「執行緒」的執行優先順序 及隸屬的「執行緒群組」。 每個「執行緒」於程式執行時的可能狀態有:born、ready、running、blocked、suspend、sleeping、waiting及dead。 Java語言實務 執行緒

各作業系統對於具有相同優先權的「執行緒」有不同的處理方式 。 Java Runtime(Java虛擬機器)會於開始執行程式前,自動為程式建立一個「執行緒」以便控制及記錄程式執行時的狀態,這個「執行緒」通稱為main thread,當main thread結束時(也就是說進入dead狀態時),程式的執行也就結束。 Java語言實務 執行緒

執行緒的程式架構 在Java程式中,「執行緒」是以「執行緒」物件來表示,亦即在程式中一個「執行緒」物件就代表了一個「執行緒」 二種指定程式中部分的程式碼給「執行緒」物件 以便執行的方式 在程式中建立Thread類別的子類別,然後直接在子類別中改寫繼承自Thread類別的run() 方法 在程式中定義界面Runnable,然後改寫Runnable的run() 方法 Java語言實務 執行緒

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

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

程式 Ex11_1 可能的執行結果: Thread 0: counter=0 Thread 1: counter=0 Java語言實務 執行緒

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

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

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

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

程式 Ex11_3 使用isAlive()及join()範例(2/2) public class AliveJoin { 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.isAlive()); System.out.println("Thread 2 is alive: " + c_2.t.isAlive());   try { c_1.t.join(); /* 等待第一個執行緒結束 */ c_2.t.join(); /* 等待第二個執行緒結束 */ } catch (InterruptedException e) {}   /* 此時二個執行緒皆已結束執行 */  } // end main } // end AliveJoin Java語言實務 執行緒

程式 Ex11_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=1 Thread: 2: counter=2 Thread: 2: counter=3 Thread 1 is alive: false Thread 2 is alive: false Java語言實務 執行緒

程式 Ex11.4 使用suspend()及resume()方法範例 (1/2) (修改Ex11_3的public class AliveJoin )以下述public class ResumeSuspend替代) public class ResumeSuspend { 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 (InterruptedException e) {} System.out.println("Thread 1 is alive: " + c_1.t.isAlive()); System.out.println("Thread 2 is alive: " + c_2.t.isAlive()); c_2.t.resume(); /* 恢復第二個執行緒的執行 */ System.out.println("Resuming Thread 2." ); } // end main } // end ResumeSuspend Java語言實務 執行緒

執行之可能結果為: 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語言實務 執行緒

執行緒的同步協調 當二個或二個以上的執行緒要使用共享的資源(或資料)時,這些執行緒就必須彼此協調存取共享資源的順序,否則就可能會有意想不到的結果出現。 synchronized 保留字 wait()及notify()方法 Java語言實務 執行緒

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

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

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

程式 Ex11_5執行後的結果為: Visitor 0: Number: 1 Visitor 1: Number: 1 Visitor 2: Number: 1 Visitor 3: Number: 1 由於各「執行緒」在還沒有完成共享資源的存取前就被其它的「執行緒」取得執行權,結果原號碼在還沒有累加更新前,就被另一個「執行緒」取得而使用,因此每個客戶取得的號碼皆為1。 Java語言實務 執行緒

解決上述取號不正確的現象,我們必須在getNumber()方法之前加上synchronized保留字,修改如下: public synchronized int getNumber() {... } Java Runtime會確保在任何一個時間點,只有一個「執行緒」可以進入含有syhchronized保留字宣告的方法。 修改後,程式執行的結果: Visitor 0: Number: 1 Visitor 1: Number: 2 Visitor 2: Number: 3 Visitor 3: Number: 4 Java語言實務 執行緒

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

程式 Ex11_6 wait()及notify()使用範例 (2/5) public synchronized void setNumber() /* 設定ticketNumber的值 */ { if (!tickenTaken) /* 如果號碼尚末被取走則等待號碼被取走後才繼續執行 */ try {wait();} catch(InterruptedException e){}; number++; /* 設定新的號碼 */ tickenTaken=false; /* 設定號碼尚未被取走 */ notify(); /* 告知等待佇列中的第一個執行緒可以進入ready狀態以便恢復執行 */ } } // end of NumberQueue   Java語言實務 執行緒

程式 Ex11_6 wait()及notify()使用範例 (3/5) class Consumer extends Thread /* 取得號碼的執行緒 */ { int ticketNumber; NumberQueue nq; public Consumer(NumberQueue nq)  { this.nq = nq; } public void run() { ticketNumber = nq.getNumber(); /* 取得一個號碼 */ } } // end of Consumer   class Producer extends Thread /* 設定新號碼的執行緒 */ { NumberQueue nq; public Producer(NumberQueue nq) { this. nq = nq; } while (true) nq.setNumber(); /* 設定新的號碼 */ } // end of Producer Java語言實務 執行緒

程式 Ex11_6 wait()及notify()使用範例 (4/5) public class NumMachine2 { public static void main(String[] args) { NumberQueue nq; /* 變數nq用來存放號碼產生器的參考 */  Consumer c0, c1, c2, c3; Producer p0; nq = new NumberQueue(0);  /* 建立號碼產生器 */ p0 = new Producer(nq);  /* 建立設定新號碼的執行緒 */ p0.start(); c0 = new Consumer(nq); /* 建立第一個取得號碼的執行緒 */ c0.start(); try {c0.join();} catch (InterruptedException e) {}; /* 等待第一個執行緒執行結束 */ c1 = new Consumer(nq);  /* 建立第二個取得號碼的執行緒 */ c1.start(); try { c1.join();} catch (InterruptedException e) {}; /* 等待第二個執行緒執行結束 */ c2 = new Consumer(nq); c2.start(); try {c2.join();} catch (InterruptedException e) {}; c3 = new Consumer(nq); c3.start(); try {c3.join();} catch (InterruptedException e) {}; Java語言實務 執行緒

執行結果: 程式 Ex11_6 wait()及notify()使用範例 (5/5) Consumer 0: Ticket Number: 1  /* 列印各執行緒取得的號碼 */ System.out.println("Consumer 0: Ticket Number: " + c0.ticketNumber); System.out.println("Consumer 1: Ticket Number: " + c1.ticketNumber); System.out.println("Consumer 2: Ticket Number: " + c2.ticketNumber); System.out.println("Consumer 3: Ticket Number: " + c3.ticketNumber); System.out.println("Press ctrl+c to stop!"); } // end of main } // end of NumMachine2 執行結果: 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語言實務 執行緒

執行緒優先權的管理 Java以優先權來決定「執行緒」的執行順序。 優先權是一個界於1(MIN_PRIORITY)至10(MAX_PRIORITY)的數值,預設值是5(NORM_PRIORITY)。 數值愈大,代表優先權愈高。高優先權的「執行緒」可以中斷低優先權的「執行緒」,以便取得執行權。 Java語言實務 執行緒

程式 Ex11.7 設定執行緒優先權範例(1/3) import java.io.*; class Accumulator extends Thread /* 宣告執行緒類別 */ { int sum; /* 記錄累加值的變數 */ boolean running = true; /* 控制迴圈執行次數的變數 */ Accumulator (int sum) /* 建構子-設定初值 */ { this.sum = sum;  } public void run() /* 執行緒的執行進入點 */ while(running) /* 累加數值 */ sum = sum + 1; Java語言實務 執行緒

程式 Ex11.7 設定執行緒優先權範例(2/3) public class Priority { public static void main(String[] args) Accumulator a1, a2;  /* 將主執行緒的優先權設為最高 */ Thread.currentThread().setPriority(Thread.MAX_PRIORITY);   a1 = new Accumulator(0);  /* 建立計算累加值的執行緒 */ a2 = new Accumulator(0); a1.setPriority(Thread.NORM_PRIORITY-3);  /* 設定執行緒的優先權值 */ a2.setPriority(Thread.NORM_PRIORITY+3); a1.setName("Accumulator_a1"); /* 設定執行緒的名稱 */ a2.setName("Accumulator_a2"); a1.start(); /* 啟動執行緒 */ a2.start(); try {Thread.sleep(1000);}  /* 主執行緒進入休眠狀態 */ catch(InterruptedException e){} Java語言實務 執行緒

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

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

「執行緒群組」的管理 執行緒 可依應用上的需求將執行緒分組,方便管理。 透過執行緒群組所提供的方法同時啟動、停止、暫停群組中的所有執行緒,或同時設定該群組之執行緒的最大優先權。 執行緒群組內也可以包含另一個執行緒群組。 Java語言實務 執行緒

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

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

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

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