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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 梁胜海 中级黑马   /  2012-11-15 09:20  /  1214 人查看  /  4 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

package com.lsh.test;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

class  ProducerConsumerDemo2
{
        public static void main(String[] args)
        {
                Resource r=new Resource();
                Producer pro=new Producer(r);
        Consumer con=new Consumer(r);
                Thread t1=new Thread(pro);
                Thread t2=new Thread(pro);
                Thread t3=new Thread(con);
                Thread t4=new Thread(con);
                t1.start();
                t2.start();
                t3.start();
                t4.start();
        }
}
class Resource
{
  private  String name;
  private int count=0;
  private boolean tag=false;
  Lock lock=new ReentrantLock();
  Condition con=lock.newCondition();

  public synchronized void set(String name) throws InterruptedException{
          lock.lock();
          try{
       while(tag){
                        con.await();
           }
                   this.name=name+"-------"+count++;

                System.out.println(Thread.currentThread().getName()+"--生产者--"+this.name);
            tag=true;
            con.signalAll();
          }finally{
                  lock.unlock();
          }
  }
   
   public synchronized void get() throws InterruptedException{
           lock.lock();
         try{
     while(!tag){
             con.await();
         }
                System.out.println(Thread.currentThread().getName()+"--+消费者+--"+this.name);
                tag=false;
       con.signalAll();
         }finally{
                 lock.unlock();
         }
         }
}

class Producer implements Runnable
{
        private Resource r=new Resource();

        Producer(Resource r){
        this.r=r;
        }
        public void run(){
     while(true){
            try {
                        r.set("商品");
                } catch (InterruptedException e) {
                       
                        e.printStackTrace();
                }
         }
        }

}
class Consumer implements Runnable
{
    private Resource r=new Resource();
        Consumer(Resource r){
        this.r=r;
        }
        public void run(){
        while(true){
            try {
                        r.get();
                } catch (InterruptedException e) {
                       
                        e.printStackTrace();
                }
        }
        }
}

评分

参与人数 1技术分 +1 收起 理由
古银平 + 1 赞一个!

查看全部评分

4 个回复

倒序浏览
你看你的set()和get()上面还加着synchronized,去掉后就能正常运行了。synchronized和 ReentrantLock他们最好不要同时使用。既然使用了ReentrantLock 那就 两个线程两个,唤醒的时候只要唤醒对方的即可。

评分

参与人数 1技术分 +1 收起 理由
古银平 + 1 赞一个!

查看全部评分

回复 使用道具 举报
iacky2 发表于 2012-11-15 11:06
你看你的set()和get()上面还加着synchronized,去掉后就能正常运行了。synchronized和 ReentrantLock他们最 ...

可惜改了后还是报错啊,虽然疏忽了一点。
回复 使用道具 举报
不会吧~我运行的时候是可以的啊~ 要不把 结果 截图发下吧~大家看看
回复 使用道具 举报
个人理解,你这个就是传说中死锁。。。虽然两个锁分别使用了2种不同的方式,哥们..好好的干嘛和自己过不去呢。。写个死锁玩
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马