A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 王雷1 中级黑马   /  2013-11-20 16:02  /  1761 人查看  /  7 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 王雷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();
        }
}
//只是循环不同,为什么效果是不一样的

评分

参与人数 1技术分 +1 收起 理由
黄炳期 + 1

查看全部评分

7 个回复

倒序浏览
for循环只是判断是否超出100张票的情况,而同步中synchronized(this),并没有判断是否会有负票的情况 只要加上一句话就Ok了。
synchronized(this)
{
         if(piao>0){
           System.out.println(Thread.currentThread().getName()+"火车票"+piao);
                                        add(1);
         }
   }

点评

此处不留分  发表于 2013-11-20 17:39
回复 使用道具 举报
既然用了对象锁,就要使用等待唤醒的机制了,怎么还继承thread类呢,没看懂。
回复 使用道具 举报 0 1
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循环操作比较好。

评分

参与人数 1技术分 +1 收起 理由
黄炳期 + 1

查看全部评分

回复 使用道具 举报
每一个回答都是一个提示。
如果问题已经解决,请及时修改主题为“提问结束”。
修改主题的方法链接
http://bbs.itheima.com/thread-89313-1-1.html
回复 使用道具 举报
(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的话,就不会往下执行同步代码块。
所以这样线程是俺去滴~~

评分

参与人数 1技术分 +1 收起 理由
To + 1

查看全部评分

回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马