黑马程序员技术交流社区

标题: 多线程卖票问题3,兄弟们帮帮忙 [打印本页]

作者: ぺsimon☆    时间: 2013-5-15 22:55
标题: 多线程卖票问题3,兄弟们帮帮忙
本帖最后由 ぺsimon☆ 于 2013-5-16 14:46 编辑
  1. /**
  2. 需求:简单的买票程序
  3. 多个窗口买票

  4. 让线程0执行同步代码块的代码,
  5. 让线程1执行同步函数的代码


  6. 问题:老师说同步代码块中的锁和同步函数中的锁要一样,而同步函数的锁是this
  7.          所以构造代码块中的锁也要是this,这样我就不懂了
  8.          
  9.          
  10. 问题1:以下的程序是Thread0先开启,判断flag=true,然后拿到了构造代码块中的锁this,这时this是Thread0对象
  11.           Thread0线程运行了一会儿,Thread1线程开启了,判断flag=false,然后拿到了同步函数中的锁,就运行同步函数show()方法,老师说
  12.           同步函数的锁是this,那么这时this就代表Thread1对象了,那么同步代码块中的锁和同步函数中的锁就不就变成一样了吗,程序就不同步了
  13.           怎么程序运行结果是正确的呢?
  14.          
  15.          
  16. 问题2:假设现在构造代码块中的锁和构造函数中的锁是一样的,那么当Thread0开启之后,只要Thread0没有运行完,那么Thread1不是就进不去吗,
  17.           为什么控制台上面还有Thread1的打印结果呢?

  18. */

  19. class Ticket implements Runnable //extends Thread
  20. {
  21.         private int t=100;
  22.         boolean flag=true;
  23.         
  24.         public void run()
  25.         {
  26.         if(flag)
  27.         while(true)
  28.         {
  29.         synchronized(this)
  30.         {
  31.         if(t>0)
  32.         {
  33.         try{Thread.sleep(10);}catch(Exception e){}
  34.         System.out.println(Thread.currentThread().getName()+"code:"+t--);
  35.         }
  36.         }
  37.         }
  38.         
  39.         else
  40.           while(true)
  41.         show();
  42.         }
  43.         public synchronized void show()
  44.         {
  45.         if(t>0)
  46.         {
  47.         try{Thread.sleep(10);}catch(Exception e){}
  48.         System.out.println(Thread.currentThread().getName()+"show:"+t--);
  49.     }

  50.     }
  51. }
  52. class TicketDemo
  53. {
  54.         public static void main(String[] args)
  55.         {
  56.         Ticket t=new Ticket();
  57.         Thread t1=new Thread(t);
  58.         Thread t2=new Thread(t);
  59.         
  60.         t1.start();
  61.                 try{Thread.sleep(5);}catch(Exception e){}
  62.         t.flag=false;

  63.         t2.start();

  64.         }
  65. }
复制代码

作者: 刘学明       时间: 2013-5-15 23:12
问题1:以下的程序是Thread0先开启,判断flag=true,然后拿到了构造代码块中的锁this,这时this是Thread0对象

          Thread0线程运行了一会儿,Thread1线程开启了,判断flag=false,然后拿到了同步函数中的锁,就运行同步函数show()方法,老师说

          同步函数的锁是this,那么这时this就代表Thread1对象了,那么同步代码块中的锁和同步函数中的锁就不就变成一样了吗,程序就不同步了

          怎么程序运行结果是正确的呢?

楼主:对于这个问题 您可能还没有把程序真正的读懂,同步代码块和同步函数是一样的 只不过老师把同步代码块和同步函数都加进去来说明如何应用 ,
判断flag flag一直是变化的 也就是说当执行同步代码块的时候 同步函数就不会执行 执行同步函数的时候 同步代码块就不会执行,也就是说Thread0 和Thread的1会随机执行同步代码块或者同步函数。
同步函数和同步代码块的锁都是this 但是同步函数和同步代码块不会同行运行 所以不会出现不同步的问题 程序结果是正确的。
作者: 刘学明       时间: 2013-5-15 23:15
问题2:假设现在构造代码块中的锁和构造函数中的锁是一样的,那么当Thread0开启之后,只要Thread0没有运行完,那么Thread1不是就进不去吗,

          为什么控制台上面还有Thread1的打印结果呢?

答:同步代码块中的锁和同步函数中的锁是一样的 ,但是同步代码块和同步函数不会同时执行, 即使锁是一样的 只能执行一个 也不会出现不同步的情况,当Thread0执行完,Thread0有可能执行的是同步代码块也有可能执行的是同步函数,执行结束 Thread1才会进入抢夺资源。
作者: librazeng    时间: 2013-5-15 23:23

1.没有规定同步代码块的锁和同步函数的锁要一样,这里是为了验证同步函数的锁是不是this.

2.this指的是你new的对象-new Ticket()的引用,在这里是synchonized表明的锁,不代表Thread1。输出结果正确恰恰说明同步代码块和同步函数都持有同一个锁,即this.
从而验证了同步函数的锁用的是this。

3.这里的运行顺序是,Thread0先运行run()方法,执行输出语句-39后,就释放锁this了。然后,Thread1抢到执行权,就可以拿到this锁,高高兴兴的运行else-44下面的语句了。
明白了吗?我也花了1个多小时,才搞清楚:
同步函数的锁用的是 this
静态同步函数的锁用的是 类名.class
作者: ぺsimon☆    时间: 2013-5-16 00:16
librazeng 发表于 2013-5-15 23:23
1.没有规定同步代码块的锁和同步函数的锁要一样,这里是为了验证同步函数的锁是不是this.

2.this指的是你 ...

明白了,原来this指的是Ticket对象,哥们还以为是Thread对象呢呵呵
作者: ぺsimon☆    时间: 2013-5-16 08:48
librazeng 发表于 2013-5-15 23:23
1.没有规定同步代码块的锁和同步函数的锁要一样,这里是为了验证同步函数的锁是不是this.

2.this指的是你 ...

兄弟,为什么this指的是new的对象-new Ticket()的引用呢?
不是线程在调用它吗?
作者: 刘胜寒    时间: 2013-5-16 10:21
楼主,你看看那是否可以结贴了啊。。。是不是啊
作者: 袁梦希    时间: 2013-5-16 11:49
楼主你好   如果帖子已经解决  请把帖子的类型改为“已解决”。
作者: ぺsimon☆    时间: 2013-5-16 14:46
袁梦希 发表于 2013-5-16 11:49
楼主你好   如果帖子已经解决  请把帖子的类型改为“已解决”。

哦,好的
作者: librazeng    时间: 2013-5-16 18:12
ぺsimon☆ 发表于 2013-5-16 08:48
兄弟,为什么this指的是new的对象-new Ticket()的引用呢?
不是线程在调用它吗?

this是指所在类的对象的引用,你查查this关键字的意思吧,好好复习一下前面的基础知识。Thread.currentThread()才指的的当前线程。
作者: ぺsimon☆    时间: 2013-5-16 23:03
librazeng 发表于 2013-5-16 18:12
this是指所在类的对象的引用,你查查this关键字的意思吧,好好复习一下前面的基础知识。Thread.currentTh ...

哦,好的谢谢




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