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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 红茶2331 中级黑马   /  2013-11-13 14:32  /  1323 人查看  /  9 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 红茶2331 于 2013-11-13 14:32 编辑
  1. //简单的买票程序

  2. class TicketDemo2
  3. {
  4.         public static void main(String[] args)
  5.         {

  6.                 Ticket p = new Ticket();   //新建实现runnable接口的子类对象
  7.         
  8.                 Thread  t1 = new Thread(p);  //通过新建线程对象传入Thread构造函数的方法,
  9.                 Thread  t2 = new Thread(p);         //新建线程,应该将p传入到thread中。
  10.                 Thread  t3 = new Thread(p);
  11.                 Thread  t4 = new Thread(p);

  12.                 t1.start();
  13.                 t2.start();           //开启线程
  14.                 t3.start();
  15.                 t4.start();

  16.         }
  17. }


  18. class Ticket implements Runnable//extends Thread
  19. {
  20.         private  static int tick = 100;
  21.         //Object obj = new Object();

  22.         public synchronized void run(){
  23.                 while(true){
  24.                         if(tick>0){
  25.                                 try{Thread.sleep(10);}catch(Exception e){}
  26.                                 System.out.println(Thread.currentThread().getName()+"...sale: "+tick--);
  27.                         }
  28.             }
  29.         }
  30.         
  31. }

  32. /*
  33. public synchronized void run(){
  34.         while(true){
  35.             show();
  36.         }
  37.     }
  38.     public synchronized void show(){
  39.         if(tick>0){
  40.             try{Thread.sleep(10);}catch(Exception e){}
  41.             System.out.println(Thread.currentThread().getName()+"...sale: "+tick--);
  42.         }
  43.     }
  44. */
复制代码
在这个线程问题中,我有一点没听明白,为什么给run()方法加上同步锁,其他线程就起不来了,

用我注释的里的程序为什么就能够让其他的线程起来呢

看完视频,知道这样用可以成功,但我就是想不明白道理啊,求解



评分

参与人数 1技术分 +1 收起 理由
黄炳期 + 1

查看全部评分

9 个回复

倒序浏览
本帖最后由 何超 于 2013-11-13 21:56 编辑

你那个循环是根本没出去的 就是说 你的第一个进去的线程一直在里面 从来没有离开过····你的第一个线程从开始到最后都没离开过while循环···其他线程根本进不来  更不谈他们出现在结果SOP的输出语句里面了
  1. //简单的买票程序

  2. class TicketDemo2
  3. {
  4.         public static void main(String[] args)
  5.         {

  6.                 Ticket p = new Ticket();   //新建实现runnable接口的子类对象
  7.         
  8.                 Thread  t1 = new Thread(p);  //通过新建线程对象传入Thread构造函数的方法,
  9.                 Thread  t2 = new Thread(p);         //新建线程,应该将p传入到thread中。
  10.                 Thread  t3 = new Thread(p);
  11.                 Thread  t4 = new Thread(p);

  12.                 t1.start();
  13.                 t2.start();           //开启线程
  14.                 t3.start();
  15.                 t4.start();

  16.         }
  17. }


  18. class Ticket implements Runnable//extends Thread
  19. {
  20.         private  static int tick = 100;
  21.         //Object obj = new Object();
  22.         
  23.          public void run()
  24.         {
  25.                  while(true)
  26.                  {
  27.                          synchronized(Ticket.class)
  28.                                          {
  29.               if(tick>0){
  30.                   System.out.println(Thread.currentThread().getName()+"...sale: "+tick--);
  31.                     }
  32.                  }
  33.                  }
  34.         }

  35. }
复制代码
这是我改的代码  改成了同步代码块 可以实现同步

评分

参与人数 1技术分 +1 收起 理由
黄炳期 + 1

查看全部评分

回复 使用道具 举报
本帖最后由 黄小贝 于 2013-11-13 18:24 编辑
Synchronization is achieved using monitors. Every object can have a monitor associated with it, so any object can synchronize blocks. Before a synchronized block can be entered, a thread needs to gain ownership of the monitor for that block. Once the thread has gained ownership of the monitor, no other thread synchronized on the same monitor can gain entry to that block (or any other block or method synchronized on the same monitor). The thread owning the monitor gets to execute all the statements in the block, and then automatically releases ownership of the monitor on exiting the block. At that point, another thread waiting to enter the block can acquire ownership of the monitor.

每一个对象都有一个监听器(monitor),每一个synchronizad()代码块的括号里面的都是一个对象,一个线程试图进入synchronizad的代码块的时候,会试图得到这个对象的monitor,其他处于同一 monitor下面的其他线程想要进入synchronizad代码块的时候就必须等待这个线程释放monitor,一个线程执行完synchronizad代码块后会自动释放monitor。

synchronizad作用于多个线程之间,你的程序里面,thread 1 首先进入 run 里面,也就得到了你ticket对象的monitor,因为是synchronizad的,所以,其他线程必须等thread 1 执行完释放 monitor 才会进入,可是那个时候票已经被卖完了




你注释的程序里面,也是有问题的,楼上已经验证

点评

FFF
+10086  发表于 2013-11-13 19:02
回复 使用道具 举报
黄小贝 发表于 2013-11-13 18:23
每一个对象都有一个监听器(monitor),每一个synchronizad()代码块的括号里面的都是一个对象, 当一个 ...

小贝童鞋对线程问题很上心啊
回复 使用道具 举报
落木萧萧 发表于 2013-11-13 18:28
小贝童鞋对线程问题很上心啊

那是,最近在怒看《java threads》,我的笔记~多多指教~

http://2925665.blog.51cto.com/2915665/1313583  (线程的创建和管理)
http://2925665.blog.51cto.com/2915665/1320221  (数据同步)
http://2925665.blog.51cto.com/2915665/1324501  (wait和notify)
回复 使用道具 举报
黄小贝 发表于 2013-11-13 18:36
那是,最近在怒看《java threads》,我的笔记~多多指教~

http://2925665.blog.51cto.com/2915665/131358 ...

翻译两字已经亮瞎我了
回复 使用道具 举报
落木萧萧 发表于 2013-11-13 18:45
翻译两字已经亮瞎我了

咳咳,程序员装逼第一条,从来不看中文资料
回复 使用道具 举报
何超 中级黑马 2013-11-13 18:53:45
8#
本帖最后由 何超 于 2013-11-13 18:55 编辑

原来还可以删除自己的楼层····
回复 使用道具 举报
谢谢大家,我好像明白一些了,看了好几个多线程的问题就懂很多了
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马