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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 谭辉 中级黑马   /  2013-3-19 23:01  /  1466 人查看  /  6 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 谭辉 于 2013-3-20 08:39 编辑
  1. class Res {
  2.         private String name;
  3.         private String sex;
  4.         boolean flag = false;

  5.         public synchronized void set(String name, String sex) {
  6.                 if (flag)
  7.                         try {
  8.                                 this.wait();
  9.                         } catch (InterruptedException e) {
  10.                                 e.printStackTrace();
  11.                         }
  12.                 this.name = name;
  13.                 this.sex = sex;
  14.                 flag = true;
  15.                 this.notify();
  16.         }

  17.         public synchronized void out() {
  18.                 if (!flag)
  19.                         try {
  20.                                 this.wait();
  21.                         } catch (InterruptedException e) {
  22.                                 e.printStackTrace();
  23.                         }
  24.                 System.out.println(this.name + "-------------" + this.sex);
  25.                 flag = false;
  26.                 this.notify();
  27.         }
  28. }

  29. class Input implements Runnable {
  30.         private Res r;

  31.         Input(Res r) {
  32.                 this.r = r;
  33.         }

  34.         public void run() {
  35.                 boolean b = true;
  36.                 while (true) {
  37.                         if (b) {
  38.                                 r.set("mike", "man");
  39.                                 b=false;
  40.                         } else {
  41.                                 r.set("丽丽", "女女女女女");
  42.                                 b=true;
  43.                         }
  44.                 }
  45.         }

  46. }

  47. class Output implements Runnable {
  48.         private Res r;

  49.         Output(Res r) {
  50.                 this.r = r;
  51.         }

  52.         public void run() {
  53.                 while (true) {
  54.                         r.out();
  55.                         }
  56.                 }
  57.         }


  58. public class InputOutputDemo {
  59.         public static void main(String[] args) {
  60.                 Res r = new Res();
  61.                 new Thread(new Input(r)).start();
  62.                 new Thread(new Output(r)).start();
  63.                 /*
  64.                 Input in = new Input(r);
  65.                 Output out = new Output(r);
  66.                 Thread t1 = new Thread(in);
  67.                 Thread t2 = new Thread(out);
  68.                 t1.start();
  69.                 t2.start();*/
  70.         }
  71. }
复制代码
假设set函数拿到了执行权和this锁,进入函数体内时如果flag为true则会进入等待,但这时set函数没有释放锁,则out函数也无法进入,线程不是卡死了吗..为什么还能运行.

评分

参与人数 1技术分 +1 收起 理由
陈丽莉 + 1

查看全部评分

6 个回复

倒序浏览
public synchronized void out() {

20.                if (!flag)

21.                        try {

22.                                this.wait(); //如果flag为true只是不会执行这一句而已,下面那句可以执行,同一段代码被锁锁上别的线程就不能进来,但这是两段不同的代码

23.                        } catch (InterruptedException e) {

24.                                e.printStackTrace();

25.                        }

26.                System.out.println(this.name + "-------------" + this.sex);

27.                flag = false;

28.                this.notify();

29.        }

评分

参与人数 1技术分 +1 收起 理由
陈丽莉 + 1

查看全部评分

回复 使用道具 举报
  1. public synchronized void set(String name, String sex) {
  2.                 if (flag)   //flag为false,还没有进入等待,直接执行this.name=name......
  3.                         try {
  4.                                 this.wait();
  5.                         } catch (InterruptedException e) {
  6.                                 e.printStackTrace();
  7.                         }
  8.                 this.name = name;
  9.                 this.sex = sex;
  10.                 flag = true;//将flag设置为true
  11.                 this.notify();//唤醒线程
  12.         }

  13.         public synchronized void out() {
  14.                 if (!flag)//!flag为false,不进入等待,直接执行输出语句。
  15.                         try {
  16.                                 this.wait();
  17.                         } catch (InterruptedException e) {
  18.                                 e.printStackTrace();
  19.                         }
  20.                 System.out.println(this.name + "-------------" + this.sex);
  21.                 flag = false;//将flag设置为false
  22.                 this.notify();//唤醒线程
  23.         }
  24. }
复制代码
我上面注释的是第一次执行的时候,执行到最后那唤醒线程时,要是想再次执行本线程,由于加了条件判断,会让它睡去,所以这样就能保证你设置一次打印一次!

评分

参与人数 1技术分 +1 收起 理由
陈丽莉 + 1

查看全部评分

回复 使用道具 举报
若还有问题,请继续追问;没有的话,请将帖子分类改成【已解决】~
回复 使用道具 举报
本帖最后由 谭辉 于 2013-3-20 08:23 编辑
谢洋 发表于 2013-3-19 23:24
public synchronized void out() {

20.                if (!flag)

你可能误解我的意思了.我问的是当out持有this锁的时候如果进入睡眠,锁还没释放,那么set拿不到this锁无法进入线程,也就无法把out唤醒了吗...
回复 使用道具 举报
假设set函数拿到了执行权和this锁,进入函数体内时如果flag为true则会进入等待,当执行this.wait()方法时会解除当前对象的锁定,自然out方法就可以执行了
回复 使用道具 举报
谭辉 中级黑马 2013-3-20 08:37:05
7#
谢达 发表于 2013-3-20 08:34
假设set函数拿到了执行权和this锁,进入函数体内时如果flag为true则会进入等待,当执行this.wait()方法时会解 ...

谢谢...原来在执行wait方法前解除了对当前对象的锁定...终于明白了
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马