Java多线程编程4--Lock的实例--实现生产者/消费者模式:一对一、多对多交替打印

1、实现生产者/消费者模式:一对一交替打印
public class MyService {
    private ReentrantLock 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("****");
            hasValue = false;
            condition.signal();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }
}
两个 自定义的线程
public class MyThread1 extends Thread {
    private MyService service;
    public MyThread1(MyService service) {
        this.service = service;
    }
    @Override
    public void run() {
        for (int i=0; i<100; i++) {
            service.set();
        }
    }
}
public class MyThread2 extends Thread{
    private MyService service;
    public MyThread2(MyService service) {
        this.service = service;
    }
    @Override
    public void run() {
        for (int i=0; i<100; i++) {
            service.get();
        }
    }
}
public class Run {
    public static void main(String[] args) throws InterruptedException {
        MyService service = new MyService();
        MyThread1 a = new MyThread1(service);
        a.start();

        MyThread2 b = new MyThread2(service);
        b.start();

    }
}
----
****
----
****
----
****
----
****
......
结果是交替打印
---------------------------------------------------------------------------------------

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

public class MyService {
    private ReentrantLock 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();   
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }

    public void get() {
        try {
            lock.lock();
            while (hasValue == false) {
                System.out.println("有可能**连续"); //就这里比上面的程序多了
                condition.await();
            }
            System.out.println("****");
            hasValue = false;
            condition.signal();   
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }
}
自定义线程同上
创建线程变多

public class Run {
    public static void main(String[] args) throws InterruptedException {
        MyService service = new MyService();
        MyThread1[] threadA = new MyThread1[10];
        MyThread2[] threadB = new MyThread2[10];

        for (int i=0; i<10; i++) {
            threadA[i] = new MyThread1(service);
            threadB[i] = new MyThread2(service);
            threadA[i].start();
            threadB[i].start();
        }
    }
}
----
有可能--连续
有可能--连续
****
有可能**连续
有可能**连续
有可能**连续
有可能**连续
有可能**连续
----
有可能--连续
有可能--连续
有可能--连续
有可能--连续
有可能--连续
......
程序运行后出现假死

    根据第3章中的notifyAll()解决方案,可以使用signalAll()方法来解决。将MyService.java类中两处signal()代码改成signalAll()后,程序得到正确运行。
    从控制台打印的日志可以发现,运行后不再出现假死状态,假死问题被解决了。
    控制台中“----”和“****”是交替输出的,但是“有可能**连续”和“有可能--连续”却不是交替输出的,有时候出现连续打印的情况。原因是程序中使用了一个Condition对象,再结合signalAll()方法来唤醒所有的线程,那么唤醒的线程就有可能是同类,所以就出现连续打印“有可能**连续”或“有可能--连续”的情况了

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值