为什么运行结果和调试的结果不一样啊

 

 

为什么这个代码运行的结果有11这个结果啊,我用debug调试的时候到10就退出了

 

package org.java.demo;

public class Demo {

	public static void main(String[] args) {
	
		MyThread mt1 =new MyThread();
		mt1.setName("窗口1:");

		MyThread mt2 =new MyThread();
		mt2.setName("窗口2:");
		
		MyThread mt3 =new MyThread();
		mt3.setName("窗口3:");
		
		mt1.start();
		mt2.start();
		mt3.start();
		
		
	}

}
package org.java.demo;

public class MyThread extends Thread {

	private static int ticket;
	private static Object obj = new Object();

	public void run() {

		while (ticket < 10) {
			synchronized (obj) {
				ticket++;
				try {
					sleep(50);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				System.out.println(Thread.currentThread().getName() + ":售出的票的编号为:" + ticket);

			}
		}

	}

}

 

因为这个ticket是临界资源,存在并发冲突的概率,

2个线程同时运行时,两边代码的顺序你是无法控制的,

while(ticket < 10){ 

// 两线程同时执行到这里,并进入了while循环,进行了2次加1,当然出现了11

 

另外,你调试是按单线程执行的,会无意识的控制步骤,所以一般不会出错。

 

解决方法就是把 while也加入 sync 同步代码块

因为调试进入断点的时候其它线程也没有执行了,就很难在调试的状态复现出多线程问题, 可以if(ticket >= 10) {

} 在这个if里面打断点试试 其它断点全部去掉,进入断点的时候就是出并发问题的时候。我可以说下为什么会出现11
比如当前ticket = 9 ,
1. 三个线程都执行完while判断的时候, 去抢锁,
2. 那第一个线程抢到了, 9变成了10 ,
3.接着第二个线程抢到了,但是判断在之前已经判断好了,所以继续执行,10变成11
4. 第三个线程亦然

在判断<10的时候,不知道锁有没有释放,就像去车站买票,只知道这个地方有票买,不知道有没有卖完就去排队,到你买了却不知道还有没有票,但是你就是要强行买(ticket++),所以就。。。,这时应该再问下还有没有票(再次判断ticket<10)