/**
多线程间通讯实例
*/
class Resource
{
private String name;
private String sex;
private boolean flag = false;

public synchronized void set(String name, String sex)
{
if (flag == true)
{
try
{
this.wait();
}
catch(InterruptedException e)
{
}
}
this.name = name;
this.sex = sex;
flag = true;
this.notify();


public synchronized void out()
{
if (flag != true)
{  
try 
{
this.wait();
}
catch (InterruptedException e)
{
}

System.out.println(name+"..+.."+sex);

flag = false;
notify();
}
}
}//=======================================
class Input implements Runnable
{
Resource r;

Input(Resource r)
{
this.r = r;
}

public void run()
{
int x = 0;
while(true)
{ if (x == 0)
{
r.set("Mike", "Male");
}
else
{
r.set("丽丽", "女女女女");
} x =(x + 1) % 2;
}
}
}
//============================================
class Output implements Runnable
{
Resource r;
Output(Resource r)
{
this.r = r;
}

public void run()
{
while(true)
{
r.out();
}

}
}
//=======================================
class ResourceDemo
{
public static void main(String[] args)
{
Resource r = new Resource();

Input in = new Input(r);
Output out = new Output(r); Thread t1 = new Thread(in);
Thread t2 = new Thread(out);

t1.start();
t2.start();
}
}我不知道哪里出了问题,形成了死锁。请高手帮忙指点一下。谢谢。

解决方案 »

  1.   


    package com.demo;/**
     多线程间通讯实例
     */
    class Resource
    {
        private String name;
        private String sex;
        private boolean flag = false;    public synchronized void set(String name, String sex)
        {
            if (flag == true)
            {
                try
                {
                    this.wait();
                }
                catch(InterruptedException e)
                {
                }
            }
            this.name = name;
            this.sex = sex;
            flag = true;
            this.notify();
        }    public synchronized void out()
        {
            if (flag != true)
            {
                try
                {
                    this.wait();
                }
                catch (InterruptedException e)
                {
                }            System.out.println(name+"..+.."+sex);            flag = false;
                notify();
            }
        }
    }//=======================================
    class Input implements Runnable
    {
        Resource r;    Input(Resource r)
        {
            this.r = r;
        }    public void run()
        {
            int x = 0;
            while(true)
            {
                System.out.println("in");
                if (x == 0)
                {
                    r.set("Mike", "Male");
                }
                else
                {
                    r.set("丽丽", "女女女女");
                }            x =(x + 1) % 2;
            }
        }
    }
    //============================================
    class Output implements Runnable
    {
        Resource r;
        Output(Resource r)
        {
            this.r = r;
        }    public void run()
        {
            while(true)
            {
                System.out.println("out");
                r.out();
            }    }
    }class ResourceDemo
    {
        public static void main(String[] args)
        {
            Resource r = new Resource();        Input in = new Input(r);
            Output out = new Output(r);        Thread t1 = new Thread(in);
            Thread t2 = new Thread(out);        t1.start();
            t2.start();
        }
    }你看输出,代码是没有死锁的
      

  2.   

    因为你程序虽然只有2个线程,但是其实是2个不同的线程,notify只能随机唤醒一个线程。你遇到的问题是jvm认为其中一个线程的优先度高于另一个线程,造成notify唤醒只能反复唤醒其中一个线程形成了死锁,建议用2个以上不同的线程时要用notifyAll()。
      

  3.   

    notify虽然有随机性,但是到jvm中还有可能产生优先差异,所以notify用的时候要小心。
      

  4.   

    JAVA多线程之wait/notify
      

  5.   

    你这两个线程用的不是一个锁。
    同步方法,是用当前对象作为锁,也就是用当前Resource 对象作为锁。而你没个线程里都有一个Resource对象,这是两个不同的对象(换在这里是有两把锁),他们各自调set()或者out()方法时,是把自己作为锁。而notify()方法只能唤醒使用相同锁的线程。所以你这个案例肯定会死锁。
      

  6.   

    因为notify方法是在执行完同步代码之后通知在阻塞队列中的线程,也就是说notify的那个线程并不是立即释放锁,而是在同步方法执行完,释放锁以后,wait方法的那个线程才会继续执行。而你那个方法里死循环,就没法释放锁了
      

  7.   

    把while改成if就可以看到效果
      

  8.   

    你同步时用了 if来判断 用notify唤醒后 不会再次判断 flag标志位,程序会继续执行下去,这里的if要换成while,每次唤醒必须进行判断