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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 刘海源 中级黑马   /  2012-7-23 13:54  /  1295 人查看  /  1 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

我的认识是:将需要同步的代码进行封装,并在该代码上加了一个锁。
      多个线程在处理同一个资源。 但是处理的动作(线程的任务)却不相同

等待唤醒机制中经典问题:生产者消费者问题。
问题在于两点:
1,本方唤醒了本方。
2,被唤醒的本方没有判断标记。只要将if判断该外while判断。
将if改为while循环判断标记后,出现了死锁。
因为本方唤醒了本方,而被唤醒的本方一判断标记,就继续等待。这样所有的线程都等待了。

必须唤醒对方才行,但是没有直接唤醒对方的动作,所以就使用了notifyAll,唤醒全部。
对吗??????求解

评分

参与人数 1技术分 +1 收起 理由
韦念欣 + 1 赞一个!

查看全部评分

1 个回复

倒序浏览
嗯,对的。
还有以下方法;

通过Lock,Condition。就可以解决这个问题了。
之前是有两个锁嵌套,容易死锁,
通过Lock,Condition创建两个监控器。
一个监视生产者,一个监视消费者。
代码实现:

*/

import java.util.concurrent.locks.*;

class Resource
{

        private String name;
        private int count = 1;
        private boolean flag;
        //创建一个锁对象。
        private final Lock lock = new ReentrantLock();
        //创建一个生产者的监视器。
        private Condition producer_con = lock.newCondition();
        //创建一个消费者监视器。
        private Condition consumer_con = lock.newCondition();
       
        public  void set(String name)//  
        {
                //获取锁。
                lock.lock();
                try
                {
               
                        while(flag)
                                try{producer_con.await();}catch(InterruptedException e){}//t0(活-->wait) t1(活)
                        this.name = name + count;//馒头1 馒头2 馒头3

                        count++;

                        System.out.println(Thread.currentThread().getName()+".....生产者......"+this.name);//Thread-0 生产 馒头1
                                                                                                                                                                                        //Thread-0 生产 馒头2
                                                                                                                                                                                        //Thread-0 生产 馒头3

                        flag = true;
                        consumer_con.signal();
                }
                finally
                {
                        //释放锁。
                        lock.unlock();
                }
        }

        public  void get()//  
        {
                lock.lock();
                try
                {
                       
               
                        while(!flag)
                                try{consumer_con.await();}catch(InterruptedException e){}//t2  t3

                        System.out.println(Thread.currentThread().getName()+".........消费者......"+this.name);//Thread-2 消费 馒头1
                        flag = false;
                        producer_con.signal();
                }
                finally
                {
                        lock.unlock();
                }
        }
}
//生产者
class Producer implements Runnable
{
        private Resource r;
        Producer(Resource r)
        {
                this.r = r;
        }
        public void run()
        {
                while(true)
                {
                        r.set("馒头");
                }
        }
}

//消费者
class Consumer implements Runnable
{
        private Resource r;
        Consumer(Resource r)
        {
                this.r = r;
        }
        public void run()
        {
                while(true)
                {
                        r.get();
                }
        }
}


class  ProConDemo4
{
        public static void main(String[] args)
        {
                Resource r = new Resource();
                Producer pro = new Producer(r);
                Consumer con = new Consumer(r);
                //两个线程负责生产。
                Thread t0 = new Thread(pro);
                Thread t1 = new Thread(pro);
                //两个线程负责消费。
                Thread t2 = new Thread(con);
                Thread t3 = new Thread(con);
                t0.start();
                t1.start();
                t2.start();
                t3.start();
        }
}

今天才学的。

哈哈哈哈。。
希望对楼主有帮助。

评分

参与人数 1技术分 +1 收起 理由
韦念欣 + 1 赞一个!

查看全部评分

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