public class Lock_and_Condition
{
    public static void main(String[] args)
    {
        Resouce re = new Resouce();        Lock lock = new ReentrantLock();        ShengChanZhe i = new ShengChanZhe(re, (ReentrantLock)lock);
        XiaoFeiZhe o = new XiaoFeiZhe(re ,(ReentrantLock)lock);        Thread t1 = new Thread(i, "生产者1");
        Thread t2 = new Thread(i, "生产者2");
        Thread t3 = new Thread(i, "生产者3");
        Thread t4 = new Thread(o, "消费者1");
        Thread t5 = new Thread(o, "消费者2");
        Thread t6 = new Thread(o, "消费者3");        t1.start();
        t2.start();
        t3.start();
        t4.start();
        t5.start();
        t6.start();
    }
}class Resouce
{
    private String name;
    private int count = 1;
    private boolean flag;    public void setName(String name) {
        this.name = name;
    }    public void setCount(int count) {
        this.count = count;
    }    public void setFlag(boolean flag) {
        this.flag = flag;
    }    public String getName() {
        return name;
    }    public int getCount() {
        return count;
    }    public boolean getFlag()
    {
        return flag;
    }
}class XiaoFeiZhe implements Runnable
{
    private Resouce res;
    private Lock lock;
    private Condition con;
    XiaoFeiZhe(Resouce re, ReentrantLock lock)
    {
        this.res = re;
        this.lock = lock;
        con = this.lock.newCondition();
    }
    public void run()
    {        while(true)
        {
            lock.lock();     //上锁,同步
            //为了执行finally语句的内容,使用try
            try
            {
                if(res.getFlag())
                {
                    System.out.println(Thread.currentThread().getName()+"-----买走了第"+res.getCount()+"个"+res.getName());
                    res.setCount(res.getCount()+1);
                    res.setFlag(false);
                    con.signalAll();          //唤醒所有等待线程,赋予执行资格
                }
                else
                {
                    try {
                        con.await();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
            finally {
                lock.unlock();
                //con.signalAll();       //唤醒所有等待线程,赋予执行资格
            }
        }
    }
}class ShengChanZhe implements Runnable
{
    private Resouce re;
    private Lock lock;
    private Condition con;
    ShengChanZhe(Resouce re, ReentrantLock lock)
    {
        this.re = re;
        this.lock = lock;
        con = this.lock.newCondition();
    }
    public void run()
    {        while(true)
        {
            lock.lock();
            try
            {
                if(re.getFlag())
                {
                    try {
                        con.await();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                else
                {
                    re.setName("混沌原核");
                    System.out.println(Thread.currentThread().getName()+"生产了第"+re.getCount()+"个"+re.getName());
                    re.setFlag(true);
                    con.signalAll();       //唤醒所有等待线程,赋予执行资格
                }
            }
            finally {
                lock.unlock();
            }
        }
    }
}上面这段代码在执行后会出现无法生产无法消费的挂起现象。。求大佬解答一下哪里错了

解决方案 »

  1.   


    你先上锁在判断flag,这里明显有问题啊,因为经常都是抢占的,如果消费者抢了生产者的锁就会无限等待下去了。你这里明显应该先判断该生产者还是消费者,也就是先判断flag,然后再3个生产者来抢锁或3个消费者来抢锁。
      

  2.   

    或者按你的思路的话,先上锁后判断flag,如果false的情况你需要先释放锁再等待,而不是直接进入等待。
      

  3.   

    感觉是因为生产者了消费者new了不同的condition
      

  4.   


    帮你修改了一下import java.util.concurrent.locks.Condition;
    import java.util.concurrent.locks.Lock;
    import java.util.concurrent.locks.ReentrantLock;public class Lock_and_Condition
    {
        public static void main(String[] args)
        {
            Resouce re = new Resouce();        Lock lock = new ReentrantLock();        ShengChanZhe i = new ShengChanZhe(re, (ReentrantLock)lock);
            XiaoFeiZhe o = new XiaoFeiZhe(re ,(ReentrantLock)lock);        Thread t1 = new Thread(i, "生产者1");
            Thread t2 = new Thread(i, "生产者2");
            Thread t3 = new Thread(i, "生产者3");
            Thread t4 = new Thread(o, "消费者1");
            Thread t5 = new Thread(o, "消费者2");
            Thread t6 = new Thread(o, "消费者3");        t1.start();
            t2.start();
            t3.start();
            t4.start();
            t5.start();
            t6.start();
        }
    }class Resouce
    {
        private String name;
        private int count = 1;
        private boolean flag;    public void setName(String name) {
            this.name = name;
        }    public void setCount(int count) {
            this.count = count;
        }    public void setFlag(boolean flag) {
            this.flag = flag;
        }    public String getName() {
            return name;
        }    public int getCount() {
            return count;
        }    public boolean getFlag()
        {
            return flag;
        }
    }class XiaoFeiZhe implements Runnable
    {
        private Resouce res;
        private Lock lock;
        private Condition con;
        XiaoFeiZhe(Resouce re, ReentrantLock lock)
        {
            this.res = re;
            this.lock = lock;
            con = this.lock.newCondition();
        }
        public void run()
        {        while(true)
            {
                lock.lock();     //上锁,同步
                //为了执行finally语句的内容,使用try
                try
                {
                    if(res.getFlag())
                    {
                        System.out.println(Thread.currentThread().getName()+"-----买走了第"+res.getCount()+"个"+res.getName());
                        res.setCount(res.getCount()+1);
                        res.setFlag(false);
                        con.signalAll(); //唤醒所有等待线程,赋予执行资格
                        lock.unlock();
                    }
                    else
                    {
                        try {
                         lock.unlock();
                            con.await();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }catch(Exception e) {
                
                }
            }
        }
    }class ShengChanZhe implements Runnable 
    {
        private Resouce re;
        private Lock lock;
        private Condition con;
        ShengChanZhe(Resouce re, ReentrantLock lock)
        {
            this.re = re;
            this.lock = lock;
            con = this.lock.newCondition();
        }
        public void run()
        {        while(true)
            {
                lock.lock();
                try
                {
                    if(re.getFlag())
                    {
                        try {
                         lock.unlock();
                            con.await();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    else
                    {
                        re.setName("混沌原核");
                        System.out.println(Thread.currentThread().getName()+"生产了第"+re.getCount()+"个"+re.getName());
                        re.setFlag(true);
                        con.signalAll();
                        //唤醒所有等待线程,赋予执行资格
                        lock.unlock();
                    }
                }catch(Exception e){
                
                }
            }
        }
    }
      

  5.   


    帮你修改了一下import java.util.concurrent.locks.Condition;
    import java.util.concurrent.locks.Lock;
    import java.util.concurrent.locks.ReentrantLock;public class Lock_and_Condition
    {
        public static void main(String[] args)
        {
            Resouce re = new Resouce();        Lock lock = new ReentrantLock();        ShengChanZhe i = new ShengChanZhe(re, (ReentrantLock)lock);
            XiaoFeiZhe o = new XiaoFeiZhe(re ,(ReentrantLock)lock);        Thread t1 = new Thread(i, "生产者1");
            Thread t2 = new Thread(i, "生产者2");
            Thread t3 = new Thread(i, "生产者3");
            Thread t4 = new Thread(o, "消费者1");
            Thread t5 = new Thread(o, "消费者2");
            Thread t6 = new Thread(o, "消费者3");        t1.start();
            t2.start();
            t3.start();
            t4.start();
            t5.start();
            t6.start();
        }
    }class Resouce
    {
        private String name;
        private int count = 1;
        private boolean flag;    public void setName(String name) {
            this.name = name;
        }    public void setCount(int count) {
            this.count = count;
        }    public void setFlag(boolean flag) {
            this.flag = flag;
        }    public String getName() {
            return name;
        }    public int getCount() {
            return count;
        }    public boolean getFlag()
        {
            return flag;
        }
    }class XiaoFeiZhe implements Runnable
    {
        private Resouce res;
        private Lock lock;
        private Condition con;
        XiaoFeiZhe(Resouce re, ReentrantLock lock)
        {
            this.res = re;
            this.lock = lock;
            con = this.lock.newCondition();
        }
        public void run()
        {        while(true)
            {
                lock.lock();     //上锁,同步
                //为了执行finally语句的内容,使用try
                try
                {
                    if(res.getFlag())
                    {
                        System.out.println(Thread.currentThread().getName()+"-----买走了第"+res.getCount()+"个"+res.getName());
                        res.setCount(res.getCount()+1);
                        res.setFlag(false);
                        con.signalAll(); //唤醒所有等待线程,赋予执行资格
                        lock.unlock();
                    }
                    else
                    {
                        try {
                         lock.unlock();
                            con.await();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }catch(Exception e) {
                
                }
            }
        }
    }class ShengChanZhe implements Runnable 
    {
        private Resouce re;
        private Lock lock;
        private Condition con;
        ShengChanZhe(Resouce re, ReentrantLock lock)
        {
            this.re = re;
            this.lock = lock;
            con = this.lock.newCondition();
        }
        public void run()
        {        while(true)
            {
                lock.lock();
                try
                {
                    if(re.getFlag())
                    {
                        try {
                         lock.unlock();
                            con.await();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    else
                    {
                        re.setName("混沌原核");
                        System.out.println(Thread.currentThread().getName()+"生产了第"+re.getCount()+"个"+re.getName());
                        re.setFlag(true);
                        con.signalAll();
                        //唤醒所有等待线程,赋予执行资格
                        lock.unlock();
                    }
                }catch(Exception e){
                
                }
            }
        }
    }
    感谢大佬,那我这样理解可以吗:await是放弃了执行资格,unlock是让出了执行权(锁),如果await先执行的话就会出现没有执行资格,但却一直占用执行权(锁),从而导致其它线程无法执行的情况?
      

  6.   

    我试着重新在主线程里面建立了一个Condition对象。。发现确实不会有抢占现象了。。但是生产者消费者本身不就是可以用不同的Condition对象来控制的吗,为什么会出现这种情况?
      

  7.   


    当然可以使用不同的Condition对象实例,但前提是要互相持有对方的实例引用。否则你如何做到生产者生产好了通知消费者进行消费呢?生产者和消费者Condition对象分开的好处还在于可以进行精确的通知控制(如消费者仅唤醒生产者),
    你现在的代码消费者线程中只能唤醒消费者,生产者同理