線程執行代碼出現結果跟老師說的不一樣
public?class?salesTicketRunnable?{
public?static?void?main(String[]?args)?{
TicketsRun?tc?=?new?TicketsRun();
Thread?a?=?new?Thread(tc,?"窗口1");
Thread?b?=?new?Thread(tc,?"窗口2");
Thread?c?=?new?Thread(tc,?"窗口3");
a.start();
b.start();
c.start();
}
}
class?TicketsRun?implements?Runnable?{
private?int?tickets?=?5;
public?void?run()?{
while?(tickets?>?0)?{
tickets--;
System.out.println(Thread.currentThread().getName()?+?"賣了一張票,票數剩余"
+?tickets);
}
}
}執行結果?
窗口1賣了一張票,票數剩余2
窗口2賣了一張票,票數剩余2
窗口3賣了一張票,票數剩余2
窗口2賣了一張票,票數剩余0
窗口1賣了一張票,票數剩余1
請問,并不是打印出來4,3,2,1,0或者是亂序的4,3,2,1,0。這是怎么回事?難道是窗口1減去一張票后,剛好打印的時候被窗口2減去一張票,然后窗口一重新獲得cpu,然后打印的時候打印出來的是窗口2減去一張票后的值嗎
2016-07-20
我覺得老師那結果是多次執行篩選出的結果,值得一提的是確實有一定概率出現老師的執行結果
2015-12-20
你的理解大致上是對的,但不是剛好打印的時候被窗口2減去一張票,過程是這樣的:
當第一個線程獲得CPU的時間片后,它的代碼恰好執行到println那一行后,剛準備輸出(但還沒有獲得tickets的值),這時候該線程的時間片被剝奪,等待下一次再獲得時間片。等到別的線程執行完后,該線程再次獲得時間片,它去訪問tickets變量,應該tickets變量是被別的線程自減過得,所以獲得不是4,而是一個比4小的值。由于這種運算在現在的CPU上很快,就會出現前三個都是2的情況。如果你給println語句加上一個synchronized同步鎖,你的結果一會一直是43210.
2015-12-20
對,你的想法是對的。要想結果和你預想的一致,就得使用線程同步機制,給線程加鎖。