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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 王海龙 中级黑马   /  2012-12-23 21:53  /  1952 人查看  /  10 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 王海龙 于 2012-12-24 12:38 编辑
  1. public class Demo implements Runnable {
  2.         private int ticket = 100;
  3.         Object obj = new Object();

  4.         @Override
  5.         public void run() {
  6.                 synchronized (obj) {
  7.                         
  8.                
  9.                 do {
  10.                         try {
  11.                                 Thread.sleep(10);
  12.                         } catch (InterruptedException e) {
  13.                                 // TODO Auto-generated catch block
  14.                                 e.printStackTrace();
  15.                         }
  16.                         System.out.println(Thread.currentThread().getName() + "***"
  17.                                         + ticket--);
  18.                 } while (ticket > 0);}
  19.         }

  20.         public static void main(String[] args) {
  21.                 Demo d = new Demo();
  22.                 Thread t1 = new Thread(d);
  23.                 Thread t2 = new Thread(d);
  24.                 Thread t3 = new Thread(d);
  25.                 Thread t4 = new Thread(d);

  26.                 t1.start();
  27.                 t2.start();
  28.                 t3.start();
  29.                 t4.start();

  30.         }

  31. }
复制代码
上边这段代码和毕老师的差不多,但是为什么还是会出现ticket<0的情况?

评分

参与人数 1技术分 +1 收起 理由
邵天强 + 1

查看全部评分

10 个回复

倒序浏览
一个县城进去就一直循环了……
回复 使用道具 举报
你这个程序肯定会出现票数负数的情况,这个条件判断放的位置就不对
do {
                        try {
                                Thread.sleep(10);
                        } catch (InterruptedException e) {
                                // TODO Auto-generated catch block
                                e.printStackTrace();
                        }
                        System.out.println(Thread.currentThread().getName() + "***"
                                        + ticket--);
                } while (ticket > 0);}
你的问题在这段代码中
更改的方式如下:
public class Demo implements Runnable {
        private int ticket = 100;
        Object obj = new Object();

        @Override
        public void run() {
                synchronized (obj) {
                        
                while (ticket > 0){
                        try {
                                Thread.sleep(10);
                        } catch (InterruptedException e) {
                                // TODO Auto-generated catch block
                                e.printStackTrace();
                        }
                        System.out.println(Thread.currentThread().getName() + "***"
                                        + ticket--);
                } }
        }

        public static void main(String[] args) {
                Demo d = new Demo();
                Thread t1 = new Thread(d);
                Thread t2 = new Thread(d);
                Thread t3 = new Thread(d);
                Thread t4 = new Thread(d);

                t1.start();
                t2.start();
                t3.start();
                t4.start();

        }

}
自己找找区别,这个不会出现负数的情况

评分

参与人数 1技术分 +1 收起 理由
邵天强 + 1

查看全部评分

回复 使用道具 举报
1、这个非常简单了
2、假如ticket等于0了,然后在第18句,好,放弃了执行权,就是没有读到while条件语句。
3、这时,另外一个线程来了,二话不说,先执行do再说,这时就输出ticket等于0了,然后再ticket减去1!
4、所以如果这时,这个线程在while条件之前,又挂着了,继续下去,还可能出现负数

评分

参与人数 1技术分 +1 收起 理由
邵天强 + 1

查看全部评分

回复 使用道具 举报
多谢        
回复 使用道具 举报
有点迷糊,还得多看论坛前辈的提问啊
回复 使用道具 举报
java技术菜鸟,现在看不懂这些程序,就知道些函数,但是我肯定很快我就会认识他们了
回复 使用道具 举报
罗海清 发表于 2012-12-24 09:08
1、这个非常简单了
2、假如ticket等于0了,然后在第18句,好,放弃了执行权,就是没有读到while条件语句。
...

犀利啊,有点像毕老师的风范。。。二话不说都用上了。
回复 使用道具 举报
Java菜鸟飘过,向各位大神学习中.....
回复 使用道具 举报
按照你的写法,一个线程得到锁,进去了,就一直在循环,知道将票卖完才退出,释放锁;第二个线程进入了,不判断票数,直接执行,这时候,产生的负数票,然后判断,退出循环;接下来的线程都在重复这个步骤。解决办法是使用while循环,将同步代码块放入while中
回复 使用道具 举报
package demo1;
public class Demo implements Runnable {
        private int ticket = 100;
        Object obj = new Object();
        @Override
        public void run() {
            synchronized (obj) {                    
             do {
                     try {
                             Thread.sleep(10);
                     } catch (InterruptedException e) {
                             // TODO Auto-generated catch block
                             e.printStackTrace();
                     }
                     System.out.println(Thread.currentThread().getName() + "***"+ ticket--);      
             } while (ticket > 0);
            }
        }
        public static void main(String[] args) {
                Demo d = new Demo();
                Thread t1 = new Thread(d);
                Thread t2 = new Thread(d);
                Thread t3 = new Thread(d);
                Thread t4 = new Thread(d);
                t1.start();
                t2.start();
                t3.start();
                t4.start();
        }
}
因为有一个线程抢到了执行权以后,就一直在循环中,因为条件一直为真,没有机会释放CPU执行权,等到条件为0时,才跳出循还,释放执行权,此时CPU又切换到其他线程,因为没有判断约束条件,当行执到输出时,就会出现小于0的情况。
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马