本帖最后由 张学永 于 2012-11-19 15:04 编辑
public void run() {
if (onlyWin) {
while (true) {
//同步语句块,使用监工this。
synchronized (this) {
if (tickets>0) {
System.out.println(Thread.currentThread().getName()+" 默认窗口售票 "+tickets--);
}else {
System.out.println(Thread.currentThread().getName()+"售票结束");
break;
}
}
}
}else {
while (true) {
if (fucSyn) {//也就是这里,当标记改变的时候,不会执行sale()方法,会执行下面的break
sale();
} else {
break;//可以在这里的break上面写个输出语句System.out.println("消失的售票员")来验证,应该是会出现两次,因 为你改变标记后,有两个线程会运行到这段代码,也就是新开的窗口。消失的情况是,一个执行了上面的sale(),一个没有执行。
}
}
}
}
//同步函数。监工默认为this,和默认售票窗口的监工是同一个。
public synchronized void sale () {
if (tickets>0) {
System.out.println(Thread.currentThread().getName()+" 新开窗口售票 "+tickets--);
}else {
System.out.println(Thread.currentThread().getName()+"售票结束");
fucSyn=false;//我觉得问题出在这个标记的问题上,当这个标记改变的时候,有和谐的情况,也有不和谐的情况,就是后开的线程里一个线程改变了标记,另一个新开的的线程窗口读到了此标记,则不会执行sale()方法,会直接执行break;而你的“售票结束”语句是定义在sale()方法上的,所以没有执行;
}
}
解决办法就是:你可以将sale()方法里面的System.out.println(Thread.currentThread().getName()+"售票结束")
剪切到
while (true) {
if (fucSyn) {
sale();
} else {
System.out.println(Thread.currentThread().getName()+"售票结束");
break;
}
}
这样就可以了~
|