黑马程序员技术交流社区

标题: 还是多线程的synchronized()问题 [打印本页]

作者: 广驰    时间: 2012-8-25 20:17
标题: 还是多线程的synchronized()问题
本帖最后由 应广驰 于 2012-8-25 20:24 编辑

  1. package ygc;

  2. class Demo implements Runnable
  3. {
  4.         private static int piao = 10;
  5.         private String name;
  6.         Demo(String name)
  7.         {
  8.                 this.name = name;
  9.         }
  10.        
  11.         public String getName()
  12.         {
  13.                 return name;
  14.         }
  15.         Object obj = new Object();
  16.        
  17.         public void run()
  18.         {
  19.                
  20.                 synchronized(obj)
  21.                 {
  22.                         while(piao>0)
  23.                         {
  24.                                 System.out.println(this.getName()+"卖出"+(10-(--piao))+"号票"+"还有"+(piao)+"张票");
  25.                         }
  26.                 }
  27.                                
  28.         }
  29. }

  30. class Test
  31. {
  32.        
  33.         public static void main(String[] arges)
  34.         {
  35.                
  36.                 Demo d1 = new Demo("一号窗口");
  37.                 new Thread(d1).start();
  38.                 Demo d2 = new Demo("二号窗口");
  39.                 new Thread(d2).start();
  40.                 Demo d3 = new Demo("三号窗口");
  41.                 new Thread(d3).start();
  42.                 Demo d4 = new Demo("四号窗口");
  43.                 new Thread(d4).start();
  44.         }
  45. }
复制代码
其中一次输出结果
一号窗口卖出1号票还有9张票
一号窗口卖出2号票还有8张票
一号窗口卖出4号票还有6张票
一号窗口卖出5号票还有5张票
一号窗口卖出6号票还有4张票
一号窗口卖出7号票还有3张票
一号窗口卖出8号票还有2张票
一号窗口卖出9号票还有1张票
一号窗口卖出10号票还有0张票
二号窗口卖出3号票还有7张票


有了synchronized(obj)不是其他线程都进不来了么,要等语句执行完才可以进来,那为什么最后一次输出的却是3和7呢。d2线程应该拿到线程执行权后就会执行然后输出了吧,怎么会在最后d1线程执行完后在输出呢。是因为双核CPU的问题吗?


作者: 唐见    时间: 2012-8-25 20:24
你在run方法内部定义同步锁obj。也就是你创建的4个线程都持有不同的锁,他们就不会具有同步功能了。要想他们有同步功能,必须让创建的多个线程使用同一个锁。
作者: 刘源    时间: 2012-8-25 20:44
因为你这4个线程都是 Object obj = new Object();,导致4个线程的锁就不一样。所以 synchronized(obj),加不加没区别。
你可以改成 synchronized(Demo.class)。这样4个线程都是同一个锁,就OK了。就达到了你要的目的






作者: 广驰    时间: 2012-8-25 20:52
已解决,要谢谢各位了!
呃,我刚刚又看了视频和代码,发现我确实创建了四个Demo对象,这个是直接在第一种创建方法上改的,怪不得呢,不过要是改成就一个Demo类,然后用四个Thread类调用的话,就无法输出“一号窗口”“二号窗口”来区分,只能输出默认的Thread-0这样的名字了,一时半会想不出来
试了好久,后来查阅了API试了下用Thread类的对象调用Thread类的setName方法和getName就可以了




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