Lock同步锁完美搞定生产者与消费者死锁问题

来源:互联网 发布:逆战一直检测数据异常 编辑:程序博客网 时间:2024/06/03 15:14

Lock同步锁解决生产者与消费者问题

这是用JDK1.5之后加入的Lock同步锁方法。

在此之前,都是用synchronized同步块或同步方法结局同步问题。但是在生产者与消费者的这个问题上,如果用synchronized就需要嵌套同步块,这样很容易就会发生死锁。(嵌套的很容易发生线程1拿了A锁,需要B锁进入内层同步块,但是B锁在线程2手上,同时B锁需要A锁进入内层同步快)

使用Lock同步锁不仅可以解决死锁问题,而且可以唤醒单个对方线程以达到提高效率的效果。如下:

import java.util.concurrent.locks.Condition;import java.util.concurrent.locks.Lock;import java.util.concurrent.locks.ReentrantLock;/** *  Lock取代同步synchronized  *  完成生产者与消费者的死锁问题,并且效率也是最高的 *  一把锁,两个监视器,两个监视器可以分别唤醒本方waitting状态的线程 * */public class LockDriver {    public static void main(String[] args) {        //一个资源对象        Resources re = new Resources("瓜皮", 1);        //一个生产任务线程对象        Productor pro = new Productor(re);        //一个消费任务线程对象        Customer cus = new Customer(re);        //实现三个生产线程执行生产任务        Thread p1 = new Thread(pro);        Thread p2 = new Thread(pro);        Thread p3 = new Thread(pro);        //实现三个消费线程执行消费任务        Thread c1 = new Thread(cus);        Thread c2 = new Thread(cus);        Thread c3 = new Thread(cus);        //启动生产和消费线程        p1.start();p2.start();p3.start();        c1.start();c2.start();c3.start();    }}//end pbl-cla/** * 资源类 */class Resources{    String name;    int num ;    boolean flag;//标记位,是否有资源    public Resources(String name, int num) {        this.name = name;        this.num = num;    }    //创建一个锁对象    Lock lock = new ReentrantLock();    //一个生产者监视器对象,一个消费者监视器对象    Condition conPro = lock.newCondition();    Condition conCus = lock.newCondition();    /*生产方法*/    public void set() {        lock.lock();//开启同步锁        try {            while(this.flag) {                //存在产品,生产者线程等待                conPro.await();            }            //表示没有产品,进入生产        System.out.println(Thread.currentThread().getName()        +" 生产==" + this.name +(this.num));            this.flag = true;            //已生产,消费者监视器conCus唤醒单独的消费者线程            conCus.signal();        } catch (Exception e) {            e.printStackTrace();        } finally {            lock.unlock();//解锁        }//end try-catch    }//end set-method    /*消费方法*/    public void get() {        //开启同步锁        lock.lock();        try {            while(!this.flag) {                //没有产品,消费者线程等待生产                conCus.await();            }            //true表示有产品,进入消费        System.out.println(Thread.currentThread().getName()            +" 消费==" + this.name + (this.num++));            this.flag = false;            //已消费,生产者监视器唤醒单独的生产者线程继续生产            conPro.signal();        } catch (Exception e) {            e.printStackTrace();        } finally {            lock.unlock();        }    }//end getMethod}//end resourse-cls/** * 生产类 */class Productor implements Runnable{    Resources r ;    public Productor(Resources r) {        this.r = r;    }    @Override    public void run() {        while(true) {            r.set();        }//end while    }//end run}//end pro-cla/** * 消费者类 */class Customer implements Runnable{    Resources r;    public Customer(Resources r) {        this.r = r;    }    @Override    public void run() {        while(true){            r.get();        }//end while    }//end run}//edn cus-cla

结果如图,生产一个,就消费一个。
生产者与消费者

原创粉丝点击