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;
    }
}
目录
相关文章
|
19天前
|
数据采集 存储 弹性计算
高并发Java爬虫的瓶颈分析与动态线程优化方案
高并发Java爬虫的瓶颈分析与动态线程优化方案
Java 数据库 Spring
58 0
|
1月前
|
算法 Java
Java多线程编程:实现线程间数据共享机制
以上就是Java中几种主要处理多线程序列化资源以及协调各自独立运行但需相互配合以完成任务threads 的技术手段与策略。正确应用上述技术将大大增强你程序稳定性与效率同时也降低bug出现率因此深刻理解每项技术背后理论至关重要.
84 16
|
2月前
|
缓存 并行计算 安全
关于Java多线程详解
本文深入讲解Java多线程编程,涵盖基础概念、线程创建与管理、同步机制、并发工具类、线程池、线程安全集合、实战案例及常见问题解决方案,助你掌握高性能并发编程技巧,应对多线程开发中的挑战。
|
2月前
|
数据采集 存储 前端开发
Java爬虫性能优化:多线程抓取JSP动态数据实践
Java爬虫性能优化:多线程抓取JSP动态数据实践
|
3月前
|
Java API 调度
从阻塞到畅通:Java虚拟线程开启并发新纪元
从阻塞到畅通:Java虚拟线程开启并发新纪元
307 83
|
3月前
|
安全 算法 Java
Java 多线程:线程安全与同步控制的深度解析
本文介绍了 Java 多线程开发的关键技术,涵盖线程的创建与启动、线程安全问题及其解决方案,包括 synchronized 关键字、原子类和线程间通信机制。通过示例代码讲解了多线程编程中的常见问题与优化方法,帮助开发者提升程序性能与稳定性。
144 0
|
3月前
|
存储 Java 调度
Java虚拟线程:轻量级并发的革命性突破
Java虚拟线程:轻量级并发的革命性突破
258 83
|
4月前
|
移动开发 Java
说一说 Java 是如何实现线程间通信
我是小假 期待与你的下一次相遇 ~