JUC:4_3并发协作模型:生产者消费者问题:精准唤醒condition、condition应用场景

JUC:4_3并发协作模型:生产者消费者问题:精准唤醒condition、condition应用场景

  • condition是什么?
  • 应用场景
  • condition精确唤醒代码
  • 结果输出

condition是什么?

JUC是Java的一个包
Package java.util.concurrent.locks
接口和类提供了一个框架,用于锁定和等待与内置同步和监视器不同的条件。

包含了三个接口,Lock、Condition、ReadWriteLock

接口 描述
Condition Condition因素出Object监视器方法( wait , notify和notifyAll )成不同的对象,以得到具有多个等待集的每个对象,通过将它们与使用任意的组合的效果Lock个实现。
Lock Lock实现提供比使用 synchronized方法和语句可以获得的更广泛的锁定操作。
ReadWriteLock A ReadWriteLock维护一对关联的locks ,一个用于只读操作,一个用于写入。

应用场景

线程之间的通信,线程A、B、C按次序执行?
如何去做?condition + 信号量标识去做

  • 1.condition:使用多个同步监视器,每个监视器去监视一个资源,这样就可以保证一个调用完成之后,再去调用另一个,实现精确的控制线程访问的顺序
  • 2.信号量表示flag,作用如下:
    • 1>定义第一个开始执行的线程:因为线程的执行是乱序的,不加while判断就无法精确的标识由那个线程开始
    • 2>定义线程的执行顺序:通过操作变量,来控制线程执行的步骤

生产场景?*

  • 点餐扫码–>弹出菜单–>选菜下单–>弹出清单类目–>吃完结账–>弹出结果
    类似的生产线中,当每个环节需要不同数量的线程去执行,就可以派上用场了

condition精确唤醒代码

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

/**
 * 线程之间的通信,线程A、B、C按次序执行?
 * 如何去做?condition + 信号量标识去做
 * 1.condition:使用多个同步监视器,每个监视器去监视一个资源,这样就可以保证一个调用完成之后,再去调用另一个,实现精确的控制线程访问的顺序
 * 2.信号量表示flag,作用如下:
 * 1>定义第一个开始执行的线程:因为线程的执行是乱序的,不加while判断就无法精确的标识由那个线程开始
 * 2>定义线程的执行顺序:通过操作变量,来控制线程执行的步骤
 * 

* 生产场景? * 点餐扫码-->弹出菜单-->选菜下单-->弹出清单类目-->吃完结账-->弹出结果 * 类似的生产线中,当每个环节需要不同数量的线程去执行,就可以派上用场了 */ public class TestCondition { public static void main(String[] args) { //操作同一个资源类ServiceImpl ServiceImpl service = new ServiceImpl(); //三个线程每个执行5次 new Thread(() -> { for (int i = 0; i < 5; i++) { service.printA(); } }, "A").start(); new Thread(() -> { for (int i = 0; i < 5; i++) { service.printB(); } }, "B").start(); new Thread(() -> { for (int i = 0; i < 5; i++) { service.printC(); } }, "C").start(); } } /** * 资源类Lock */ class ServiceImpl { //仅限本类使用,因此使用private修饰 private Lock lock = new ReentrantLock();//锁 private Condition conditionA = lock.newCondition();//同步监视器 private Condition conditionB = lock.newCondition();//同步监视器 private Condition conditionC = lock.newCondition();//同步监视器 /** * flag=1 A执行 * flag=2 B执行 * flag=3 C执行 */ private int flag = 1;//判断执行谁的变量,同时也是判断谁先执行,不使用此变量就会随机一个线程开始,然后有序执行 public void printA() { lock.lock();//同一把锁,因此不可能同时进入 try { //业务代码:判断-->执行-->通知 while (flag != 1) {//不用if,if会有虚假唤醒 //等待 conditionA.await(); } System.out.println(Thread.currentThread().getName() + "===A方法==="); //唤醒等待的指定线程:B flag = 2; conditionB.signal(); } catch (Exception e) { e.printStackTrace(); } finally { lock.unlock(); } } public void printB() { lock.lock();//同一把锁,因此不可能同时进入 try { //业务代码:判断-->执行-->通知 while (flag != 2) {//不用if,if会有虚假唤醒 //等待 conditionB.await(); } System.out.println(Thread.currentThread().getName() + "===B方法==="); //唤醒等待的指定线程:C flag = 3; conditionC.signal(); } catch (Exception e) { e.printStackTrace(); } finally { lock.unlock(); } } public void printC() { lock.lock();//同一把锁,因此不可能同时进入 try { //业务代码:判断-->执行-->通知 while (flag != 3) {//不用if,if会有虚假唤醒 //等待 conditionC.await(); } System.out.println(Thread.currentThread().getName() + "===C方法==="); //唤醒等待的指定线程:A flag = 1; conditionA.signal(); } catch (Exception e) { e.printStackTrace(); } finally { lock.unlock(); } } }

结果输出

A===A方法===
B===B方法===
C===C方法===
A===A方法===
B===B方法===
C===C方法===
A===A方法===
B===B方法===
C===C方法===
A===A方法===
B===B方法===
C===C方法===
A===A方法===
B===B方法===
C===C方法===

你可能感兴趣的:(并发编程,java,面试,多线程,经验分享)