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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 王桂丽 中级黑马   /  2012-8-16 00:20  /  1353 人查看  /  3 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

/*
线程间通讯:
其实就是多个线程在操作同一个资源,
但是操作的动作不同。
*/
class Res//定义资源
{
String name;
String sex;
boolean flag=false;
}
class Input implements Runnable//定义类Input实现Runnable接口
{
private Res r;
Input(Res r)
  {
   this.r=r;
  }
public void run()//覆盖run方法
  {
   int x=0;
   while(true)
   {
    synchronized(r)
     {
    if(r.flag)
     try{r.wait();}catch(Exception e){}//等待机制
   
    if(x==0)
    {
    r.name="mike";
    r.sex="man";
    }
    //System.out.println(r.name+"....."+r.sex);
    else
    {
       r.name="丽丽";
    r.sex="女女女女";
    }
        }
    x=(x+1)%2;
    r.flag=true;
    r.notify();//唤醒机制
   }
  }
}
class Output implements Runnable//定义类Output实现Runnable
{
private Res r;
Output(Res r)
  {
   this.r=r;
  }
public void run()
  {
  while(true)
   {
   synchronized(r)
    {
    if(!r.flag)
     try{r.wait();}catch(Exception e){}//等待机制
    System.out.println(r.name+"....."+r.sex);
    r.flag=false;
    r.notify();//唤醒机制
    }
   }
  }
}
class  InputOutputDemo1
{
public static void main(String[] args)
{
  Res r=new Res();
  Input in=new Input(r);
  Output out=new Output(r);
  Thread t1=new Thread(in);
  Thread t2=new Thread(out);
  t1.start();
  t2.start();
  //System.out.println("Hello World!");
}
}
问题:1、毕老师课程中讲到“等待和唤醒必须是同一个锁”,那是不是说Input类中的notify唤醒的是Input类中的wait(),Output类中的notify唤醒的是Output类中的wait()?如果不是那执行顺序又是怎样的呢?
          2、代码是哪里出了问题,为什么运行不了呢?运行时结果如图。

未命名.jpg (22.43 KB, 下载次数: 9)

未命名.jpg

3 个回复

倒序浏览
class InputOutputDemo1 {
                 public static void main(String[] args) {

                Res r = new Res();
                Input in = new Input(r);
                Output out = new Output(r);
                Thread t1 = new Thread(in);
                Thread t2 = new Thread(out);
                t1.start();
                t2.start();
                // System.out.println("Hello World!");
        }
}

class Res// 定义资源
{
        String name;
        String sex;
        boolean flag = false;
}

class Input implements Runnable// 定义类Input实现Runnable接口
{
        private Res r;

        Input(Res r) {
                this.r = r;
        }
public void run()//覆盖run方法
  {
           int x=0;
           while(true)
           {
                    synchronized(r)
                     {
                                    if(r.flag)
                                     try{r.wait();}catch(Exception e){}//等待机制
                                    
                                    if(x==0)
                                    {
                                            r.name="mike";
                                            r.sex="man";
                                    }
                                    //System.out.println(r.name+"....."+r.sex);
                                    else
                                    {
                                       r.name="丽丽";
                                       r.sex="女女女女";
                                    }
                                    r.flag=true;
                                    r.notify();//唤醒机制
//你刚才把这写字那个大括号的外面了当然性质都变了
                        }
                                    x=(x+1)%2;
                 }
          }
}
class Output implements Runnable//定义类Output实现Runnable
{
private Res r;

        Output(Res r) {
                this.r = r;
        }

        public void run() {
                while (true) {
                        synchronized (r) {
                                if (!r.flag)
                                        try {
                                                r.wait();
                                        } catch (Exception e) {
                                        }// 等待机制
                                System.out.println(r.name + "....." + r.sex);
                                r.flag = false;
                                r.notify();// 唤醒机制
                        }
                }
        }
}
其实很简单的问题,这个问题希望你以后写代码的时候把格式一定要对齐,
回复 使用道具 举报
        notify()
          唤醒在此对象监视器上等待的单个线程.....

在这个例子中,对象就是R   
因为就只有2个线程,所以,T1 就只能唤醒T2
但是当多个线程的时候, 就会出现,它唤醒的不一定就是对立面的等待的线程,
所以,会出现,都WAIT,的情况,也就是假死机的情况,
这个时候我们就要用  notifyAll来,避免这个情况的发生。
回复 使用道具 举报
此问题已解决
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马