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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© yhnan 中级黑马   /  2013-4-6 11:24  /  1338 人查看  /  3 人回复  /   1 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 易贺男 于 2013-4-6 18:40 编辑
  1. class Sisuo
  2. {
  3.         public static void main(String[] args)
  4.         {
  5.                 Person p = new Person();
  6.                 Input in = new Input(p);
  7.                 Output out = new Output(p);
  8.                 Thread t = new Thread(in);
  9.                 Thread t1 = new Thread(out);
  10.                 t.start();
  11.                 t1.start();
  12.         }
  13. }
  14. //两个线程一个输入一个输出
  15. class Person
  16. {
  17.         String name;
  18.         String sex;
  19.         boolean flang = false;
  20. }
  21. class Input implements Runnable
  22. {
  23.         private  Person n;
  24.         Input(Person n)
  25.         {
  26.                 this.n = n;
  27.         }
  28.         public void run()
  29.         {
  30.                 int x = 0 ;
  31.                 while(true)
  32.                 {
  33.                         
  34.                         synchronized(n)
  35.                         {
  36.                                 if(n.flang)
  37.                                 try{n.wait();}catch(Exception e){}//wait,notify.为什么是放在同步的里边?
  38.                                 if(x==0)
  39.                                 {
  40.                                         n.name="zhangsan";
  41.                                         n.sex="nan";
  42.                                 }
  43.                                 else
  44.                                 {
  45.                                         n.name="拉拉";
  46.                                         n.sex="女";
  47.                                 }
  48.                                 x=(x+1)%2;
  49.                                 n.flang=true;
  50.                                 n.notify();
  51.                         }
  52.                 }
  53.         }
  54. }
  55. class Output implements Runnable
  56. {
  57.         private Person n;
  58.         Output(Person n)
  59.         {
  60.                 this.n = n;

  61.         }
  62.         public void run()
  63.         {
  64.                 while(true)
  65.                 {
  66.                         
  67.                         synchronized(n)
  68.                         {
  69.                         if(!n.flang)
  70.                                 try{n.wait();}catch(Exception e){}//.......?
  71.                         System.out.println(n.name+"...."+n.sex);
  72.                         
  73.                         n.flang=false;
  74.                         n.notify();
  75.                         }
  76.                 }
  77.         }
  78. }
复制代码
为什么wait和notify是放在同步里边的?我的理解是:因为input和output用的是同一个锁,如果放在里边那么负责input的线程等待之后,只释放了执行权,没有放锁,那之后Output的线程岂不是进不来。可是通过代码的运行已经证明我的理解是错误的,但我还是转不过来。求各位指点

评分

参与人数 1技术分 +1 收起 理由
冯海霞 + 1

查看全部评分

3 个回复

倒序浏览
{:soso_e199:}wait和notify是针对同步锁的等待唤醒操作,所以放在同步块中才有意义,另外,你的理解是错的,wait方法调用不止释放了执行权同时也释放了锁,因此持有同一个所的线程在其他线程wait之后是能够进来的。

评分

参与人数 1技术分 +1 收起 理由
冯海霞 + 1

查看全部评分

回复 使用道具 举报
我帮你找的比较规范点说法:
为什么要使用线程通信?
1.当使用synchronized 来修饰某个共享资源时(分同步代码块和同步方法两种情况),当某个线程获得共享资源的锁后就可以执行相应的代码段,直到该线程运行完该代码段后才释放对该共享资源的锁,让其他线程有机会执行对该共享资源的修改。
2.当某个线程占有某个共享资源的锁 时,如果另外一个线程也想获得这把锁运行就需要使用wait() 和notify()/notifyAll()方法来进行线程通讯了。

结合上面两句话举个例子:就是你上面的例子,如果不用wait,notify的话,只能按第一条说的来执行,这样就很可能出现cpu在一直执行该线程,不切换到另一个线程。(一直执行输出,zhangsan,nan一堆,拉拉,女一堆)如果我想控制让两者交替输出呢?
                        也就是赋一次值,输出一次。这时候用到第二条。
关于wait(JDK):
前提:当前线程必须拥有此 对象监视器(锁)。
该线程发布(放弃)对此监视器(锁)的所有权并等待,直到其他线程通过调用 notify 方法,
或 notifyAll 方法通知 在此对象的监视器上等待 的线程醒来.
然后该线程将等到 重新获得对监视器的所有权后 才能继续执行。

评分

参与人数 1技术分 +1 收起 理由
冯海霞 + 1

查看全部评分

回复 使用道具 举报
若还有问题,请继续追问; 没有的话,将帖子分类改成【已解决】~
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马