为了账号安全,请及时绑定邮箱和手机立即绑定

线程执行代码出现结果跟老师说的不一样

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下载
官方微信