朱西瓜
2015-12-19 11:48
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减去一张票后的值吗
我觉得老师那结果是多次执行筛选出的结果,值得一提的是确实有一定概率出现老师的执行结果
你的理解大致上是对的,但不是刚好打印的时候被窗口2减去一张票,过程是这样的:
当第一个线程获得CPU的时间片后,它的代码恰好执行到println那一行后,刚准备输出(但还没有获得tickets的值),这时候该线程的时间片被剥夺,等待下一次再获得时间片。等到别的线程执行完后,该线程再次获得时间片,它去访问tickets变量,应该tickets变量是被别的线程自减过得,所以获得不是4,而是一个比4小的值。由于这种运算在现在的CPU上很快,就会出现前三个都是2的情况。如果你给println语句加上一个synchronized同步锁,你的结果一会一直是43210.
对,你的想法是对的。要想结果和你预想的一致,就得使用线程同步机制,给线程加锁。
细说多线程之Thread VS Runnable
55327 学习 · 68 问题
相似问题