黑马程序员技术交流社区
标题:
线程卖票的为什么会出错
[打印本页]
作者:
王雷1
时间:
2013-11-20 16:02
标题:
线程卖票的为什么会出错
本帖最后由 王雷1 于 2013-11-21 10:22 编辑
为什么只能用while循环,for循环就出错,还是 我写的有毛病
class chezan implements Runnable
{
int piao=100;
int sum;
public void add(int x)
{
sum=sum+x;
System.out.println(sum);
}
public void run()
{
for(this.piao=100;this.piao>0;this.piao--)
{
synchronized(this)
{
System.out.println(Thread.currentThread().getName()+"火车票"+piao);
add(1);
}
}
}
}
class ti//正好是103张,好几次都是这个结果
{//如果不是正好的103张我还能理解为线程,但是好几次都是103张
public static void main(String[] args)
{
chezan t=new chezan();
Thread x1=new Thread(t);
Thread x2=new Thread(t);
Thread x3=new Thread(t);
Thread x4=new Thread(t);
x1.start();
x2.start();
x3.start();
x4.start();
}
}
//只是循环不同,为什么效果是不一样的
作者:
″先森丶玹°
时间:
2013-11-20 16:31
for循环只是判断是否超出100张票的情况,而同步中synchronized(this),并没有判断是否会有负票的情况 只要加上一句话就Ok了。
synchronized(this)
{
if(piao>0){
System.out.println(Thread.currentThread().getName()+"火车票"+piao);
add(1);
}
}
作者:
hurryup
时间:
2013-11-20 16:51
既然用了对象锁,就要使用等待唤醒的机制了,怎么还继承thread类呢,没看懂。
作者:
@ne_pie尒ce
时间:
2013-11-20 16:54
for(this.piao=100;this.piao>0;this.piao--)
for()参数列表中有对共享数据的操作this.piao--,而你没有把他放进同步代码块中
自然会出现卖出负数票的情况,线程是不安全的。
而把对共享数据的操作放进同步代码块中
synchronized(this)
{
for(this.piao=100;this.piao>0;this.piao--)
{
synchronized(this)
{
System.out.println(Thread.currentThread().getName()+"火车票"+piao);
add(1);
}
}
}
这样每个线程都会有100张票,也是不符合需求的。
因此还是有while循环操作比较好。
作者:
黄炳期
时间:
2013-11-20 17:39
每一个回答都是一个提示。
如果问题已经解决,请及时修改主题为“提问结束”。
修改主题的方法链接
http://bbs.itheima.com/thread-89313-1-1.html
作者:
smileven
时间:
2013-11-20 19:19
(1) for(this.piao=100;this.piao>0;this.piao--)
{synchronized(this); }
这种方法对票的数量判断是在synchronized同步代码块的外面。
当票已经卖完,但是如果有线程已经经过了for语句中piao>0的判断,那么肯定会出现负数票。
(2) while(true)
synchronized(this)
{if(piao > 0)
}
这种方法是将票的数量的判断放在synchronized同步代码跨里面,
虽然有线程进入同步代码块中等待,但是piao的值为0的话,就不会往下执行同步代码块。
所以这样线程是俺去滴~~
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/)
黑马程序员IT技术论坛 X3.2