使用LOCK锁实现 生产者消费者问题 以及实现精准通知

在之前入门学习中的生产者消费者问题里 是使用的synchronized wait() notifyAll()实现
https://www.cnblogs.com/OfflineBoy/p/14613402.html
现在尝试使用lock锁实现 同时做到解耦
lock对应的两个函数在condition类里面

代码例子

package com.jie.demo2;

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

public class PCdemo {
    public static void main(String[] args) {
        Data data=new Data();
        new Thread(()->{
            for(int i=0;i<10;i++){
                try{
                    data.increment();
                }
                catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        },"A").start();
        new Thread(()->{
            for(int i=0;i<10;i++){
                try{
                    data.decrement();
                }
                catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        },"B").start();
        new Thread(()->{
            for(int i=0;i<10;i++){
                try{
                    data.increment();
                }
                catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        },"C").start();
        new Thread(()->{
            for(int i=0;i<10;i++){
                try{
                    data.decrement();
                }
                catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        },"D").start();

    }
}
class Data{
    private int number=0;
    Lock lock=new ReentrantLock();
    Condition condition = lock.newCondition();
    public void increment() throws InterruptedException {
        try{
            lock.lock();
            while(number!=0){
                condition.await();
            }
            number++;
            System.out.println(Thread.currentThread().getName()+"=>"+number);
            condition.signalAll();
        }
        catch (Exception e){

        }
        finally {
            lock.unlock();
        }
    }
    public void decrement() throws InterruptedException {
        try{
            lock.lock();
            while(number==0){
                condition.await();
            }
            number--;
            System.out.println(Thread.currentThread().getName()+"=>"+number);
            condition.signalAll();
        }
        catch (Exception e){
            e.printStackTrace();
        }
        finally {
            lock.unlock();
        }
    }
}

实现精准通知

在上面例子里我们是直接通知所有正在等待进程,同时我们是可以实现精准通知的 下面是简单例子
代码:

package com.jie.demo2;

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

public class C {
    //通过精准通知实现ABC运行的顺序
    public static void main(String[] args) {
        Data2 data2=new Data2();
        new Thread(()->{
            for(int i=0;i<10;i++){
                data2.printA();
            }
        },"A").start();
        new Thread(()->{
            for(int i=0;i<10;i++){
                data2.printB();
            }
        },"B").start();
        new Thread(()->{
            for(int i=0;i<10;i++){
                data2.printC();
            }
        },"C").start();
    }

}
class Data2{
    public Data2() {
    }

    private Lock lock=new ReentrantLock();
    Condition condition1 = lock.newCondition();
    Condition condition2 = lock.newCondition();
    Condition condition3 = lock.newCondition();
    private int number=1;
    public void printA(){
        lock.lock();
        try{
            while(number!=1){
                condition1.await();
            }
            System.out.println("A");
            number=2;
            condition2.signal();
        }
        catch (Exception e){
            e.printStackTrace();
        }
        finally {
            lock.unlock();
        }
    }
    public void printB(){
        lock.lock();
        try{
            while(number!=2){
                condition2.await();
            }
            System.out.println("B");
            number=3;
            condition3.signal();
        }
        catch (Exception e){
            e.printStackTrace();
        }
        finally {
            lock.unlock();
        }
    }
    public void printC(){
        lock.lock();
        try{
            while(number!=3){
                condition3.await();
            }
            System.out.println("C");
            number=1;
            condition1.signal();
        }
        catch (Exception e){
            e.printStackTrace();
        }
        finally {
            lock.unlock();
        }
    }
}

posted @ 2021-09-08 19:03  一个经常掉线的人  阅读(71)  评论(0)    收藏  举报