Java线程 管程法和信号灯法

简介: Java线程 管程法和信号灯法

管程法

并发协作模型,"生产者/消费者模式"-->管程法

  1. 生产者:负责生产数据的模块(可能是方法,对象,线程,进程);
  2. 消费者:负责处理数据的模块(可能是方法,对象,线程,进程);
  3. 缓冲区:消费者不能直接使用生产者的数据,他们之间有个缓冲区

生产者将生产好的数据放到缓存区,消费者从缓存区拿出数据

代码例子


package com.wyh.thread;
/**
 * @program: Thread
 * @description: 测试:生产者消费者模型  利用缓冲区解决:管程法
 * @author: 魏一鹤
 * @createDate: 2022-01-19 23:14
 **/
//测试:生产者消费者模型  利用缓冲区解决:管程法
//需要 生产者 消费者 产品 缓冲区
public class TestPC {
public static void main(String[] args){
//容器
        SynContainer synContainer = new SynContainer();
//生产者
        new Productor(synContainer).start();
//消费者
        new Consumer(synContainer).start();
    }
}
//生产者
class Productor extends Thread{
//缓冲区
    SynContainer container;
//有参构造
    public Productor(SynContainer container){
this.container=container;
    }
//生产
    @Override
public void run() {
for (int i = 0; i < 100; i++) {
//循环插入
            try {
container.push(new Chicken(i));
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("生产了"+i+"只鸡");
        }
    }
}
//消费者
class Consumer extends Thread{
//缓冲区
    SynContainer container;
//有参构造
    public Consumer(SynContainer container){
this.container=container;
    }
//消费
    @Override
public void run() {
for (int i = 0; i < 100; i++) {
try {
                System.out.println("消费了"+container.pop().num+"只鸡");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
//产品 鸡
class Chicken{
//编号
    int num;
//有参构造
    public Chicken(int num) {
this.num = num;
    }
}
//缓冲区
class SynContainer{
//需要一个容器大小  初始大小为10
    Chicken[] chickens=new Chicken[10];
//容器计数器
    int count=0;
//生产者生产产品 同步方法
    public synchronized void push(Chicken chicken) throws InterruptedException {
//如果容器满了 就需要等待消费者消费
        if(count==chickens.length){
//容器满了 通知消费者消费,生产等待
            this.wait();
        }
//如果没有满,就需要丢入产品
        chickens[count] = chicken;
count++;
//可以通知消费者消费了
        this.notifyAll();
    }
//消费者消费产品
    public synchronized Chicken pop() throws InterruptedException {
//判断能否消费
        if(count==0){
//没有产品 等待生产者生产,消费者等待
            this.wait();
        }
//如果可以消费 消费
        count--;
        Chicken chicken=chickens[count];
//吃完了 通知生产者生产
        this.notifyAll();
return chicken;
    }
}


信号灯法

并发协作模型 ,"生产者/消费者模式"-->信号灯法

通过boolean标识来进行判断(红路灯)


package com.wyh.thread;
/**
 * @program: Thread
 * @description: 测试生产者 消费者问题2:信号灯法,标志位解决
 * @author: 魏一鹤
 * @createDate: 2022-01-22 18:35
 **/
//定义boolean表示解决
public class TestPC2 {
public static void main(String[] args){
        TV tv = new TV();
//生产者表演
        new Player(tv).start();
//消费者观看
        new Watcher(tv).start();
    }
}
//生产者 演员
class Player extends  Thread{
    TV tv;
//构造方法
    public Player(TV tv) {
this.tv = tv;
    }
    @Override
public void run() {
//生产者表演节目
        for (int i = 0; i < 20; i++) {
if(i%2==0){
try {
this.tv.play("快乐大本营");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }else{
try {
this.tv.play("抖音");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
//消费者 观众
class Watcher extends  Thread{
    TV tv;
//构造方法
    public Watcher(TV tv) {
this.tv = tv;
    }
//消费者观看节目
    @Override
public void run() {
for (int i = 0; i < 20; i++) {
try {
this.tv.watch();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
//产品 节目
class TV{
//演员表演 观众等待 true
    //观众观看 演员等待 false
    String voice;//表演的节目
    boolean flag=true; //等待标识符
    //表演
    public synchronized  void play(String voice) throws InterruptedException {
if(!flag){
this.wait();//等待
        }
        System.out.println("演员表演了:" + voice);
//通知观众观看
        this.notifyAll();//通知唤醒
        this.voice=voice;
this.flag=!this.flag;
    }
//观看
    public synchronized  void watch() throws InterruptedException {
//如果flag为true 那就还没表演
        if(flag){
this.wait();//等待
        }
        System.out.println("观众观看了:" + voice);
//通知演员表演
        this.notifyAll();//通知唤醒
        this.flag=!this.flag;
    }
}
目录
相关文章
|
11天前
|
监控 安全 Java
在 Java 中使用线程池监控以及动态调整线程池时需要注意什么?
【10月更文挑战第22天】在进行线程池的监控和动态调整时,要综合考虑多方面的因素,谨慎操作,以确保线程池能够高效、稳定地运行,满足业务的需求。
88 38
|
8天前
|
安全 Java
java 中 i++ 到底是否线程安全?
本文通过实例探讨了 `i++` 在多线程环境下的线程安全性问题。首先,使用 100 个线程分别执行 10000 次 `i++` 操作,发现最终结果小于预期的 1000000,证明 `i++` 是线程不安全的。接着,介绍了两种解决方法:使用 `synchronized` 关键字加锁和使用 `AtomicInteger` 类。其中,`AtomicInteger` 通过 `CAS` 操作实现了高效的线程安全。最后,通过分析字节码和源码,解释了 `i++` 为何线程不安全以及 `AtomicInteger` 如何保证线程安全。
java 中 i++ 到底是否线程安全?
|
13天前
|
Java 调度
[Java]线程生命周期与线程通信
本文详细探讨了线程生命周期与线程通信。文章首先分析了线程的五个基本状态及其转换过程,结合JDK1.8版本的特点进行了深入讲解。接着,通过多个实例介绍了线程通信的几种实现方式,包括使用`volatile`关键字、`Object`类的`wait()`和`notify()`方法、`CountDownLatch`、`ReentrantLock`结合`Condition`以及`LockSupport`等工具。全文旨在帮助读者理解线程管理的核心概念和技术细节。
30 1
[Java]线程生命周期与线程通信
|
3天前
|
存储 设计模式 分布式计算
Java中的多线程编程:并发与并行的深度解析####
在当今软件开发领域,多线程编程已成为提升应用性能、响应速度及资源利用率的关键手段之一。本文将深入探讨Java平台上的多线程机制,从基础概念到高级应用,全面解析并发与并行编程的核心理念、实现方式及其在实际项目中的应用策略。不同于常规摘要的简洁概述,本文旨在通过详尽的技术剖析,为读者构建一个系统化的多线程知识框架,辅以生动实例,让抽象概念具体化,复杂问题简单化。 ####
|
4天前
|
Java 开发者
在Java多线程编程的世界里,Lock接口正逐渐成为高手们的首选,取代了传统的synchronized关键字
在Java多线程编程的世界里,Lock接口正逐渐成为高手们的首选,取代了传统的synchronized关键字
19 4
|
4天前
|
消息中间件 供应链 Java
掌握Java多线程编程的艺术
【10月更文挑战第29天】 在当今软件开发领域,多线程编程已成为提升应用性能和响应速度的关键手段之一。本文旨在深入探讨Java多线程编程的核心技术、常见问题以及最佳实践,通过实际案例分析,帮助读者理解并掌握如何在Java应用中高效地使用多线程。不同于常规的技术总结,本文将结合作者多年的实践经验,以故事化的方式讲述多线程编程的魅力与挑战,旨在为读者提供一种全新的学习视角。
24 3
|
10天前
|
安全 Java
在 Java 中使用实现 Runnable 接口的方式创建线程
【10月更文挑战第22天】通过以上内容的介绍,相信你已经对在 Java 中如何使用实现 Runnable 接口的方式创建线程有了更深入的了解。在实际应用中,需要根据具体的需求和场景,合理选择线程创建方式,并注意线程安全、同步、通信等相关问题,以确保程序的正确性和稳定性。
|
5天前
|
安全 Java 调度
Java中的多线程编程入门
【10月更文挑战第29天】在Java的世界中,多线程就像是一场精心编排的交响乐。每个线程都是乐团中的一个乐手,他们各自演奏着自己的部分,却又和谐地共同完成整场演出。本文将带你走进Java多线程的世界,让你从零基础到能够编写基本的多线程程序。
17 1
|
9天前
|
缓存 Java 调度
Java中的多线程编程:从基础到实践
【10月更文挑战第24天】 本文旨在为读者提供一个关于Java多线程编程的全面指南。我们将从多线程的基本概念开始,逐步深入到Java中实现多线程的方法,包括继承Thread类、实现Runnable接口以及使用Executor框架。此外,我们还将探讨多线程编程中的常见问题和最佳实践,帮助读者在实际项目中更好地应用多线程技术。
17 3
|
11天前
|
监控 安全 Java
Java多线程编程的艺术与实践
【10月更文挑战第22天】 在现代软件开发中,多线程编程是一项不可或缺的技能。本文将深入探讨Java多线程编程的核心概念、常见问题以及最佳实践,帮助开发者掌握这一强大的工具。我们将从基础概念入手,逐步深入到高级主题,包括线程的创建与管理、同步机制、线程池的使用等。通过实际案例分析,本文旨在提供一种系统化的学习方法,使读者能够在实际项目中灵活运用多线程技术。