07-传统的生产者消费者问题、防止虚假唤醒

07-传统的生产者消费者问题、防止虚假唤醒

锁是什么,如何判断锁的是谁?

4、生产者和消费者问题

Synchronized 版本 wait 和 notify可以实现
JUC 版本 lock

生产者和消费者问题 Synchronized 版本

package com.hkx.pc;

/**
 * @program: juc
 * @description: A类
 * @author: Casey Hu
 * @create: 2022-07-31 19:05
 **/


/**
 * 线程之间的通讯问题:生产者和消费者问题
 * 线程交替执行 A 线程 B线程 操作同一个变量 num=0
 * 在A线程执行num加一的操作
 * B线程之后执行num减一的操作
 * 解决:使用通知唤醒,等待唤醒
 */
public class A {
    
    
    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) {
    
    
                    throw new RuntimeException(e);
                }
            }
        },"A").start();
        new Thread(()->{
    
    
            for (int i=0;i<10;i++){
    
    
                try {
    
    
                    data.decrement();
                } catch (InterruptedException e) {
    
    
                    throw new RuntimeException(e);
                }
            }
        },"B").start();

    }
}
/**
* @Description: 资源类
* @Param:
* @return:
* @Author: Casey Hu
* @Date: 2022/7/31
*/
//判断等待,业务,通知
class Data{
    
    
    private int number=0;

    //加一操作
    public synchronized void increment() throws InterruptedException {
    
    
        if (number!=0){
    
    
           this.wait(); //等待操作
        }
        number++;
        System.out.println(Thread.currentThread().getName()+"=>"+number);
        //通知其他线程,完成了加一操作
        this.notifyAll();
    }
    //减一操作
    public synchronized void decrement() throws InterruptedException {
    
    
        if (number==0){
    
    
            this.wait();
        }
        number--;
        System.out.println(Thread.currentThread().getName()+"=>"+number);
        //通知其他线程,完成了减一操作
        this.notifyAll();
    }
}

问题存在,A B C D 4个线程 虚假唤醒

在这里插入图片描述
要把if 判断改成 while 判断

package com.hkx.pc;

/**
 * @program: juc
 * @description: A类
 * @author: Casey Hu
 * @create: 2022-07-31 19:05
 **/


/**
 * 线程之间的通讯问题:生产者和消费者问题
 * 线程交替执行 A 线程 B线程 操作同一个变量 num=0
 * 在A线程执行num加一的操作
 * B线程之后执行num减一的操作
 * 解决:使用通知唤醒,等待唤醒
 */
public class A {
    
    
    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) {
    
    
                    throw new RuntimeException(e);
                }
            }
        },"A").start();
        new Thread(()->{
    
    
            for (int i=0;i<10;i++){
    
    
                try {
    
    
                    data.decrement();
                } catch (InterruptedException e) {
    
    
                    throw new RuntimeException(e);
                }
            }
        },"B").start();
        new Thread(()->{
    
    
            for (int i=0;i<10;i++){
    
    
                try {
    
    
                    data.increment();
                } catch (InterruptedException e) {
    
    
                    throw new RuntimeException(e);
                }
            }
        },"C").start();
        new Thread(()->{
    
    
            for (int i=0;i<10;i++){
    
    
                try {
    
    
                    data.decrement();
                } catch (InterruptedException e) {
    
    
                    throw new RuntimeException(e);
                }
            }
        },"D").start();
    }
}
/**
* @Description: 资源类
* @Param:
* @return:
* @Author: Casey Hu
* @Date: 2022/7/31
*/
//判断等待,业务,通知
class Data{
    
    
    private int number=0;

    //加一操作
    public synchronized void increment() throws InterruptedException {
    
    
        while (number!=0){
    
    
           this.wait(); //等待操作
        }
        number++;
        System.out.println(Thread.currentThread().getName()+"=>"+number);
        //通知其他线程,完成了加一操作
        this.notifyAll();
    }
    //减一操作
    public synchronized void decrement() throws InterruptedException {
    
    
        while (number==0){
    
    
            this.wait();
        }
        number--;
        System.out.println(Thread.currentThread().getName()+"=>"+number);
        //通知其他线程,完成了减一操作
        this.notifyAll();
    }
}

08-Lock版的生产者消费者问题

JUC版的生产者和消费者问题

在这里插入图片描述
其中的await() 方法属于 condition
在这里插入图片描述

通过Lock可以找到Condition

在这里插入图片描述

在这里插入图片描述
代码实现:

package com.hkx.pc;

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

/**
 * @program: juc
 * @description: JUC版的生产者和消费者问题
 * @author: Casey Hu
 * @create: 2022-08-07 21:41
 **/

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

    Lock lock=new ReentrantLock();
    Condition condition = lock.newCondition();
//        condition.await();   //等待
//        condition.signalAll(); //唤醒全部
    //加一操作
    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) {
    
    
            throw new RuntimeException(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) {
    
    
            throw new RuntimeException(e);
        } finally {
    
    
            lock.unlock();
        }

    }
}

任何新技术的创新,绝对不是仅仅只是覆盖了原来的技术,优势和补充

Condition 精准的通知和唤醒线程

在这里插入图片描述
接下来,要进行有序执行A B C D 的唤醒

猜你喜欢

转载自blog.csdn.net/qq_43658218/article/details/126089182
今日推荐