黑马程序员技术交流社区

标题: 关于Thread中买票的程序问题。 [打印本页]

作者: 绿影    时间: 2011-11-13 23:53
标题: 关于Thread中买票的程序问题。
将共享数据和操作数据的方法一并封装到Runnable的实现子类中,然后在主方法中new其实例对象,将这个实例对象传个创建的两个匿名Thread对象,并开启运行。为何出现诡异的结果呢?具体问题见代码注释,麻烦大家帮忙瞅瞅!谢谢先!
  1. public class SaleTickets{
  2.         //static Tickets  tickets = new Tickets();//这里和(1)处除了他是随类的创建而创建,
  3.                                                 //存储在静态区,以及共享外还有什么区别吗?
  4.         public static void main(String[] args) {
  5.                  Tickets  tickets = new Tickets();//(1)
  6.                 new Thread(tickets).start();//调用tickets身上的run方法将count--
  7.             new Thread(tickets).start();//也是调用tickets身上的run方法将count--       
  8.         }
  9. }
  10. //将共享数据和操作数据的方法一并封装到Runnable的实现子类中
  11. class Tickets implements Runnable{
  12.         private int count = 10000;
  13.         @Override
  14.         public /*synchronized*/ void  run(){//这里为何加上同步另外一个进程就无法启动呢?
  15.                 while(true){
  16.                  count--;
  17.                  System.out.println(Thread.currentThread().getName()+"|"+count);//打印出来的结果也非常怪异居然有负数
  18.                 }       
  19.         }
  20. }
复制代码

作者: 坚强    时间: 2011-11-14 08:35
  因为你一同步了,就是拿到锁的线程运行里面的代码,如果你的代码是一个简单的打印输出语句,则它打印输出就完了,下一个线程就进来了,两个线程就会交替运行,但是你的程序中是一个循环,而且会一直执行,知道票没了,所以另一个线程就进不了。
  简单的说就是:若某个线程进入synchronized里面的代码,它会运行完里面所有的代码才会出去,包括在里面谁觉的时间。
作者: 宋文轩    时间: 2011-11-14 08:40
首先  这个代码的结果出现了负数 是没有在run方法的while循环里加上判断语句,所以导致了count一直减小 所以出现了负数的情况。可以在count--前面加上if(count>0)来判断。
再有  家上synchronized 不是不让另一个线程启动,而是通过同步使一个线程执行这个语句的时候,因为有锁的原因,在这个线程没有执行结束的时候 另一个线程是不能够进入run方法来执行的,这样数据就安全了。否则当0线程执行到第0张print语句的时候 1线程抢cpu执行权,那么1线程就会执行run方法,这样就造成了两条语句都执行了run方法,导致了最后出现-1张票的可能性。而事实上应该是最后第0张票的时候只有一个线程来执行才可以。所以加上了同步,使一个线程在没有执行完同步中的内容的时候,另一个线程是没有办法执行的,这样安全性就高了。
作者: 坚强    时间: 2011-11-14 08:41
  问下,你没弄错,为什么我的JDK1.7 运行你的代码数据会无限增大 压根没有减少?
作者: 绿影    时间: 2011-11-21 19:32
恩 是有问题。逻辑上有问题。




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