ReentrantLock实现生产者消费者模式

ReentrantLock 实现生产者消费者模式

实现生产者消费者模式:一对一交替打印

public class MyService {

    private Lock lock = new ReentrantLock();

    private Condition condition = lock.newCondition();

    private boolean hasValue = false;

    public void set() {
        try {
            lock.lock();
            while (hasValue == true) {
                condition.await();
            }
            System.out.println("打印 *");
            hasValue = true;
            condition.signal();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }

    public void get() {
        try {
            lock.lock();
            while (hasValue == false) {
                condition.await();
            }
            System.out.println("打印 o");
            hasValue = false;
            condition.signal();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }

}

public class ThreadA extends Thread {

    private MyService myService;

    public ThreadA(MyService myService) {
        super();
        this.myService = myService;
    }

    @Override
    public void run() {
        for (int i = 0; i < Integer.MAX_VALUE; i++) {
            myService.set();
        }
    }
}

public class ThreadB extends Thread {

    private MyService myService;

    public ThreadB(MyService myService) {
        super();
        this.myService = myService;
    }

    @Override
    public void run() {
        for (int i = 0; i < Integer.MAX_VALUE; i++) {
            myService.get();
        }
    }
}

public class Run {
    public static void main(String[] args) throws InterruptedException {
        MyService myService = new MyService();
        ThreadA a = new ThreadA(myService);
        a.setName("A");
        a.start();
        ThreadB b = new ThreadB(myService);
        b.setName("B");
        b.start();
    }
}

程序输出结果:

// 通过使用Condition对象,成功实现交替打印的效果

打印 o
打印 *
打印 o
打印 *
打印 o
打印 *

实现生产者消费者模式:多对多交替打印

public class MyService {

    private Lock lock = new ReentrantLock();

    private Condition condition = lock.newCondition();

    private boolean hasValue = false;

    public void set() {
        try {
            lock.lock();
            while (hasValue == true) {
                System.out.println("有可能**连续");
                condition.await();
            }
            System.out.println("打印 *");
            hasValue = true;
            //            造成程序假死
//            condition.signal();
            condition.signalAll();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }

    public void get() {
        try {
            lock.lock();
            while (hasValue == false) {
                System.out.println("有可能oo连续");
                condition.await();
            }
            System.out.println("打印 o");
            hasValue = false;
//            造成程序假死
//            condition.signal();
            condition.signalAll();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }

}

    public static void main(String[] args) throws InterruptedException {
        MyService myService = new MyService();
        ThreadA[] threadA = new ThreadA[10];
        ThreadB[] threadB = new ThreadB[10];

        for (int i = 0; i < 10; i++) {
            threadA[i] = new ThreadA(myService);
            threadB[i] = new ThreadB(myService);
            threadA[i].start();
            threadB[i].start();
        }
        // 使用condition.signal()运行后出现假死
        // 根据第3章中的notifyAll()解决方案,可以使用signalAll()方法来解决.
        // 将MyService.java类中的两处signal()代码改成signalAll()后,程序得到正确运行
    }
}

程序输出:

打印 o
有可能oo连续
有可能oo连续
有可能oo连续
打印 *
有可能**连续
有可能**连续
有可能**连续
打印 o
有可能oo连续
有可能oo连续
有可能oo连续
打印 *
有可能**连续
有可能**连续

控制台中"打印*" 和"打印o"是交替输出的,但是"有可能** 连续" 和 "有可能oo连续"却不是交替输出的,

有时候出现连续打印的情况.原因是程序中使用了一个Condition对象,再结合signalAll()方法来唤醒所有的线程,

那么唤醒的线程就有可能是 同类,所以就出现连续打印"有可能**连续" 或 "有可能oo连续"的情况了.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值