黑马程序员技术交流社区

标题: 多线程!卖票问题! [打印本页]

作者: relice    时间: 2014-11-26 12:36
标题: 多线程!卖票问题!
在主函数的中,我对Thread类做了两种方法的传参:
     1.建立Ticket对象用Ticket的引用传参
     2.用了Ticket的匿名对象对Thread传参
     1.的输出结果:20张票被共享了
     2.的输出结果:20张票没有共享,Thread-0与Thread-1各自卖出了20张.
问题:这两种传参不是一样的吗,为什么输出结果不一样?
  1. class Ticket implements Runnable
  2. {
  3.   private  int tick = 20;
  4.         public void run()
  5.                 {
  6.                         while(true)
  7.                         {
  8.                                 if(tick>0)                        System.out.println(Thread.currentThread().getName()+" Ticket: "+tick--);
  9.                                 else
  10.                                 break;
  11.                         }                       
  12.                 }

  13. class T2
  14. {
  15.         public static void main(String[] args)
  16.         {
  17.                 Ticket t = new Ticket();
  18.                 Thread t1 = new Thread(t);
  19.                 Thread t2 = new Thread(t);
  20.                 t1.start();
  21.                 t2.start();
  22.         }
  23. }
复制代码




作者: 李天富    时间: 2014-11-26 12:57
匿名对象传参的话,你怎么给两个线程传同一个对象进去?结果必然是不共享的啊。
作者: Rain2692    时间: 2014-11-26 13:02
本帖最后由 Rain2692 于 2014-11-26 13:04 编辑

你在测试一下,我怎么感觉不对呢?加上Sleep看看,我觉得效果是一样的,只是你的数据太少了,说是共享,我感觉太牵强了,没加同步代码块。。。
作者: 980344791    时间: 2014-11-26 13:35
实现Runnable接口它启动的是不同的线程,但是传的参数是同一个实现类的子类,所以它的数据是共享的,而继承Thread类就不同了,共享数据要用static修饰
作者: relice    时间: 2014-11-26 14:21
李天富 发表于 2014-11-26 12:57
匿名对象传参的话,你怎么给两个线程传同一个对象进去?结果必然是不共享的啊。 ...

Ticket t = new Ticket();
                Thread t1 = new Thread(t);
                Thread t2 = new Thread(t);
与下面有区别么
Thread t1 = new Thread(new Ticker());
Thread t2 = new Thread(new Ticker());
作者: relice    时间: 2014-11-26 14:24
Rain2692 发表于 2014-11-26 13:02
你在测试一下,我怎么感觉不对呢?加上Sleep看看,我觉得效果是一样的,只是你的数据太少了,说是共享,我 ...

同步代码块的作用不就是  共同输出对吧 比如Thread-0输出 ticket 1  的同时Thread-1输出 ticket 2两个线程共同输出
作者: mmppp    时间: 2014-11-26 14:39
匿名对象的话,就相当于是两个对象了,就是两个20张的票了啊,当然是不共享的。

要使用匿名对象,确保该对象只被使用一次。
作者: FlyFish    时间: 2014-11-26 14:46
relice 发表于 2014-11-26 14:21
Ticket t = new Ticket();
                Thread t1 = new Thread(t);
                Thread t2 = n ...

匿名是俩对象,走的各自的线程
作者: zhangyangLengen    时间: 2014-11-26 15:00
可能线程的安全性保证不了
作者: 李天富    时间: 2014-11-26 15:41
relice 发表于 2014-11-26 14:21
Ticket t = new Ticket();
                Thread t1 = new Thread(t);
                Thread t2 = n ...

有区别啊,上面是一个对象,下面是两个对象。每new一次就建立一个新的对象。
作者: Rain2692    时间: 2014-11-26 22:56
relice 发表于 2014-11-26 14:24
同步代码块的作用不就是  共同输出对吧 比如Thread-0输出 ticket 1  的同时Thread-1输出 ticket 2两个线 ...

是共享资源的输出,不过怎么样最好是定义静态的资源,这样两者的输出就一样了,创建两个对象使用的锁和单个对象的锁必然不同,单个的this锁就ok,两个的就要加静态锁了,同步代码块的锁是有区别的吗,所以归根结底他们都不是真正意义上的同步,共享资源就会出问题。。。。
作者: 白衣布士    时间: 2014-11-27 00:07
新人报到:lol
作者: 米和饭    时间: 2014-11-28 11:19
relice 发表于 2014-11-26 14:21
Ticket t = new Ticket();
                Thread t1 = new Thread(t);
                Thread t2 = n ...

区别就大了,上面的只创建一个对象,而下面的创建了2个对象
作者: 康师傅-蛋黄派    时间: 2014-11-28 11:57
看来楼主和我一样是零基础的,记住:对于匿名对象只能用一次,用两次以上必须建立对象。
代码中,你new了两次,其实可以理解为你建立了两个ticket,而每个线程用了一次,所以不是共享的。
作者: wtjohn    时间: 2014-11-28 12:54
匿名对象,两次new不就有两个对象了么,要实现下面这种写法,可以借助单例设计模式
作者: 斷灬dian    时间: 2015-1-4 21:50
来学习!!




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