亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定

線程執行代碼出現結果跟老師說的不一樣

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減去一張票后的值嗎

正在回答

3 回答

我覺得老師那結果是多次執行篩選出的結果,值得一提的是確實有一定概率出現老師的執行結果

0 回復 有任何疑惑可以回復我~

你的理解大致上是對的,但不是剛好打印的時候被窗口2減去一張票,過程是這樣的:

當第一個線程獲得CPU的時間片后,它的代碼恰好執行到println那一行后,剛準備輸出(但還沒有獲得tickets的值),這時候該線程的時間片被剝奪,等待下一次再獲得時間片。等到別的線程執行完后,該線程再次獲得時間片,它去訪問tickets變量,應該tickets變量是被別的線程自減過得,所以獲得不是4,而是一個比4小的值。由于這種運算在現在的CPU上很快,就會出現前三個都是2的情況。如果你給println語句加上一個synchronized同步鎖,你的結果一會一直是43210.

1 回復 有任何疑惑可以回復我~
#1

sxian_wang

有點筆誤,你需要把自減操作和輸出語句一起用synchonized鎖起來。
2015-12-20 回復 有任何疑惑可以回復我~

對,你的想法是對的。要想結果和你預想的一致,就得使用線程同步機制,給線程加鎖。

0 回復 有任何疑惑可以回復我~

舉報

0/150
提交
取消

線程執行代碼出現結果跟老師說的不一樣

我要回答 關注問題
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號