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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 张帅 黑马帝   /  2011-12-29 02:25  /  3431 人查看  /  4 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 张帅 于 2011-12-29 03:53 编辑

以下是代码,视频上的例子,这个wait()和notify那不理解,不明白 input 和 output 是怎么切换的。
两个线程的时候好说,按照顺寻,使用  r.notify(); ,将线程2开启,接着input接着运行, 到 if(r.flag){ try{r.wait();}catch(Exception e){} },使用的都是 r 锁,他怎么知道要关闭1线程,而不是2线程呢,  因为外面有个synchronized(r){,所以 2 线程未执行,所以只能关闭 1线程(这里理解错误,虽然是同一个对象锁,但是在不同的线程run里执行的,在那个线程里执行, 就 wait 谁,
)
,接着 1 一关闭,2  是 while (true),所以侦测到了,对象不占用了,所以2运行,是不是这样的?
  1. class Res{
  2.         String name;
  3.         String sex;
  4.         boolean flag = false;
  5. }
  6. class Input implements Runnable{
  7.         private Res r;
  8.         Object obj = new Object();
  9.         Input(Res r){
  10.                 this.r = r;
  11.         }
  12.         public void run(){
  13.                 boolean b = true;
  14.                 while(true){
  15.                         synchronized(r){
  16.                                 if(r.flag){
  17.                                         try{r.wait();}catch(Exception e){}
  18.                                 }
  19.                                 if(b){
  20.                                         r.name = "mike";
  21.                                         r.sex = "man";
  22.                                         b = false;
  23.                                 }else{
  24.                                         r.name = "丽丽";
  25.                                         r.sex = "女女女女";
  26.                                         b = true;
  27.                                 }
  28.                                 r.flag = true;
  29.                                 r.notify();
  30.                         }
  31.                 }
  32.         }
  33. }
  34. class Output implements Runnable{
  35.         private Res r;
  36.         Object obj = new Object();
  37.         Output(Res r){
  38.                 this.r = r;
  39.         }
  40.         public void run(){
  41.                 while(true){
  42.                         synchronized(r){
  43.                                 if(!r.flag){
  44.                                         try{r.wait();}catch(Exception e){}
  45.                                 }
  46.                                 System.out.println(r.name+"...."+r.sex);
  47.                                 r.flag = false;
  48.                                 r.notify();
  49.                         }
  50.                 }
  51.         }
  52. }
  53. public class Demo{
  54.     public static void main(String[] args){
  55.                 Res r = new Res();
  56.                 Input in = new Input(r);
  57.                 Output out = new Output(r);
  58.                 Thread t1 = new Thread(in);
  59.                 Thread t2 = new Thread(out);
  60.                 t1.start();
  61.                 t2.start();
  62.         }
  63. }
复制代码
该贴已经同步到 张帅的微博

4 个回复

倒序浏览
本帖最后由 monghuan 于 2011-12-29 11:19 编辑

理解对的。谁(指某个线程)拿到同步锁,调用wait(此方法只应由作为此对象监视器的所有者的线程来调用)后,谁就会放弃cpu执行权。
回复 使用道具 举报
T1线程运行的是 Input类中的Run方法,t2线程运行的是Output里的Run方法
他们通过标记flag来切换的,当一线程执行到 if(r.flag){ try{r.wait();}catch(Exception e){} },如果flag为真,t1线程就会被冻结,放弃执行权并释放锁,如果此时T2线程有执行权,那么他就运行,flag标记为真,那么!真就假,他不执行wait(),并执行打印,把标记改为假,执行notiy唤醒了线程池中的T1线程,就算此时执行权被T1抢走,他也不能执行Input里面的Run方法,因为锁在T2手上,只有当T2执行完同步里面的语句才会释放锁

评分

参与人数 1技术分 +1 收起 理由
admin + 1

查看全部评分

回复 使用道具 举报
付星 黑马帝 2011-12-29 17:22:39
板凳
这个程序是开启了两个线程,第一个顺序运行着,第二个线程根据要wait(),当第一个线程notify()后,相当于给对方发起通知,如果有多个线程,启动哪个等待的就不确定了,这里只有一个等待的,所以第二线程就唤醒了,再打印第一个线程给r对象赋的值

总的来说就是第二线程每次等待第一个线程赋完值再唤起它来打印

评分

参与人数 1技术分 +1 收起 理由
admin + 1

查看全部评分

回复 使用道具 举报
wait()是线程等待,而notify则是用来唤醒调用该方法的对象上等待的单个现成,有一点要注意  这些方法都必须在synchronied代码块里面使用

评分

参与人数 1技术分 +1 收起 理由
admin + 1

查看全部评分

回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马