黑马程序员技术交流社区

标题: 学习毕老师多线程视频时的问题 [打印本页]

作者: 王海龙    时间: 2012-12-23 21:53
标题: 学习毕老师多线程视频时的问题
本帖最后由 王海龙 于 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的情况?


作者: 王海龙    时间: 2012-12-23 22:45
一个县城进去就一直循环了……
作者: 周亮    时间: 2012-12-23 23:12
你这个程序肯定会出现票数负数的情况,这个条件判断放的位置就不对
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();

        }

}
自己找找区别,这个不会出现负数的情况
作者: 罗海清    时间: 2012-12-24 09:08
1、这个非常简单了
2、假如ticket等于0了,然后在第18句,好,放弃了执行权,就是没有读到while条件语句。
3、这时,另外一个线程来了,二话不说,先执行do再说,这时就输出ticket等于0了,然后再ticket减去1!
4、所以如果这时,这个线程在while条件之前,又挂着了,继续下去,还可能出现负数

作者: 王海龙    时间: 2012-12-24 12:38
多谢        
作者: 雷傲    时间: 2012-12-25 16:21
有点迷糊,还得多看论坛前辈的提问啊
作者: yufeng47    时间: 2012-12-27 23:49
java技术菜鸟,现在看不懂这些程序,就知道些函数,但是我肯定很快我就会认识他们了

作者: 王少雷    时间: 2012-12-28 11:48
罗海清 发表于 2012-12-24 09:08
1、这个非常简单了
2、假如ticket等于0了,然后在第18句,好,放弃了执行权,就是没有读到while条件语句。
...

犀利啊,有点像毕老师的风范。。。二话不说都用上了。
作者: 黄文伯    时间: 2013-1-3 20:10
Java菜鸟飘过,向各位大神学习中.....
作者: 黄锦成    时间: 2013-1-6 15:26
按照你的写法,一个线程得到锁,进去了,就一直在循环,知道将票卖完才退出,释放锁;第二个线程进入了,不判断票数,直接执行,这时候,产生的负数票,然后判断,退出循环;接下来的线程都在重复这个步骤。解决办法是使用while循环,将同步代码块放入while中
作者: 熊永标    时间: 2013-1-6 23:05
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的情况。





欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2