多執行緒之--4個視窗售200張票
技能點:
1.如何保證執行緒是多執行緒執行,而且不出現負票?
第一個while判斷是外部判斷,用於保持售票;而且在while迴圈中嵌入synchronized (){}是慣用方法,如果此處把while換為if執行多次後會出錯;
注意同步鎖,物件為this;
第二個if是內部判斷,用於解決最後一張票的問題,防止出現0或負票。所以如果先執行輸出後做if判斷是沒有意義的。
2.梳理實現Runnable 介面與繼承Thread類的異同與利弊?
(1)實現Runnable 介面
實現Runnable介面並不意味著就是執行緒,所以在測試類中要new Thread();
對於通過實現Runnable介面來建立執行緒的方法,通過Thread.currentThread()來呼叫Thread類中的常用方法。
優點:可以繼承其他類,而且多個執行緒可以共用一個變數;
缺點:程式設計稍微複雜一些
(2)繼承Thread類
setName(); getName(); start()是Thread 類中的方法,只有通過繼承Thread類這種方法來建立執行緒時才可以直接使用;
優點:程式設計簡單
缺點:已經繼承了Thread 類,無法繼承其他類;
程式碼展示之實現Runnable 介面來建立執行緒
@java
package ticketnum;
public class TicketRunnable implements Runnable{
int ticketnum = 200;
@Override public void run() { while(ticketnum>0){ synchronized(this){ if(ticketnum > 0 ){ System.out.println(Thread.currentThread()+"售出第"+(ticketnum--)+"張票"); try { Thread.currentThread().sleep(200); } catch (InterruptedException e) { e.printStackTrace(); } } } } }
}`
編寫一個測試類
public class TestTicket {
public static void main(String[] args) {
TicketRunnable tr = new TicketRunnable();
Thread t1 = new Thread(tr,"視窗A");
Thread t2 = new Thread(tr,"視窗B");
Thread t3 = new Thread(tr,"視窗C");
Thread t4 = new Thread(tr,"視窗D" );
t1.start();
t2.start();
t3.start();
t4.start();
}
}
執行即可。
由於四個視窗共享200張票,如果用繼承Thread類的方法來解決是行不通的。
(1)如果建立4個視窗,每建立一個物件,就會有200張票,所以會出現每一個視窗都買200張,最後共賣了800張票的情況;
(2)如果只新建立一個售票視窗物件,然後呼叫4次start()方法,也是行不通的,因為一個執行緒只能被呼叫一次。