当前位置:主页 > 查看内容

java-多线程管程法,信号灯法

发布时间:2021-06-24 00:00| 位朋友查看

简介:java-多线程管程法信号灯法 1.管程法 生产者负责生产数据的模块(可能是方法对象线程进程) 消费者负责处理数据的模块(可能是方法对象线程进程) 缓冲区消费者不能直接使用生产者的数据 他们之间有个缓冲区生产者将生产好的数据放入缓冲区消费者从缓冲区拿出数……

java-多线程管程法,信号灯法

1.管程法:

生产者:负责生产数据的模块(可能是方法,对象,线程,进程)
消费者:负责处理数据的模块(可能是方法,对象,线程,进程)
缓冲区:消费者不能直接使用生产者的数据,他们之间有个缓冲区,生产者将生产好的数据放入缓冲区,消费者从缓冲区拿出数据

思路:
1.首先有一个生产者,消费者、生产者只顾生产,消费者只管消费
2.利用了一个缓冲区,缓冲了一个10个大小的数组
3.有个方法叫放入产品,产品丢进来的时候,我们判断一下缓冲区有没有满,如果满了的话,生产者就要等待了,
如果没有满,就将产品放进去,放进去之后有产品了,赶紧通知消费者消费
4.消费者就判断下能不能消费呢,有没有东西,有东西的话,我就可以直接消费,消费完了,就赶紧通知生产者生产。
如果没有东西呢,消费者就等待。等待生产者去通知他,生产者通知了,他就可以解除等待了,所以在这一块存在我们的wait()和notify()。
这里的wait()和notify()都是Object提供的:
wait()导致当前线程等待,直到另一个线程调用该对象的notify()或notifyAll()方法。
notify()唤醒正在等待对象监视器的单个线程。
一旦加了wait()之后同样是进入了阻塞状态,但是这个阻塞和之前的sleep()不一样,它会释放锁,被wait()的线程可以把这个锁交给其他线程去用,否则这个资源就一直被其持有了。

思路有了那么就开始代码部分了:

(1)创建生产者

// 生产者
class Productor extends Thread{

    SynContainer container;

    public Productor(SynContainer container){
        this.container = container;
    }

    // 生产
    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            container.push(new Bug(i));
            System.out.println("生产了"+i+"个bug");
        }
    }
}

(2)创建消灭者

// 消灭bug者
class Consumer extends Thread{

    SynContainer container;

    public Consumer(SynContainer container){
        this.container = container;
    }

    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            System.out.println("消灭了-->"+container.pop().id+"个bug");
        }
    }
}

(3)创建bug区(产品区)

// bug产品
class Bug{
    int id;// bug编号
    public Bug(int id){
        this.id = id;
    }
}

(4)创建同步代码块(缓冲区)

// 缓冲区
class SynContainer{
    // 需要一个容器大小
    Bug[] bugs = new Bug[10];
    // 容器计算器
    int count = 0;

    // 生产者放入bug
    public synchronized void push(Bug bug){
        // 如果容器满了,就需要等待消灭bug
        if(count==bugs.length){
            // 通知消灭bug者消灭,生产bug等待
            try {
                //导致当前线程等待,直到另一个线程调用该对象的 notify()方法或 notifyAll()方法。
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        // 如果没有满,我们就需要继续生产bug
        bugs[count] = bug;
        count++;

        // 可以通知消灭者消灭了
        this.notifyAll();
        // notifyAll唤醒正在等待对象监视器的所有线程。
    }

    // 消灭者消灭bug
    public synchronized Bug pop(){

        // 判断能否消灭
        if (count == 0){
            // 等待生产者生产,消灭者等待
            try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        // 如果可以消灭
        count--;
        Bug bug = bugs[count];

        // 消灭完了,通知生产者生产
        return bug;
    }
}

保证容器中没有产品的时候生产产品,不能消费;容器中产品满了的时候,不能再去生产产品

(5)创建测试类

public class Test {
    public static void main(String[] args) {
        SynContainer container = new SynContainer();
        new Productor(container).start();
        new Consumer(container).start();
    }
}

(6)测试
在这里插入图片描述

很完美的把全部bug都消灭了

2.信号灯法:

先来理解下信号灯法是什么意思:来判断一个标志位flag,如果为true,就让他等待、如果为false,就让他去通知另外一个人、把两人衔接起来,就像咱们的信号灯红灯停,绿灯行,通过这样一个判断方式,只要来判断什么瑞后让他等待,什么时候将他唤醒就ok。

话不多说直接上代码^^

package com.macro.mall.bo;
//测试生产者消费者问题2:信号灯法,通过标志位解决

public class Test {
    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) {
                this.tv.play("什么是快乐星球");
            } else {
                this.tv.play("如果你想知道什么是快乐星球的话,那我就带你研究研究");
            }
        }
    }
}

//消费者-->观众
class Watcher extends Thread {
    TV tv;

    public Watcher(TV tv) {
        this.tv = tv;
    }

    @Override
    public void run() {
        for (int i = 0; i < 20; i++) {
            tv.watch();
        }
    }
}

//产品-->节目
class TV {
    //演员表演,观众等待 T
    //观众观看,演员等待 F
    String voice; // 表演的节目
    boolean flag = true;


    //表演
    public synchronized void play(String voice) {

        if (!flag) {
            try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.println("演员表演了:" + voice);
        //通知观众观看
        this.notifyAll();
        this.voice = voice;
        this.flag = !this.flag;
    }

    //观看
    public synchronized void watch() {
        if (flag) {
            try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.println("观看了:" + voice);
        //通知演员表演
        this.notifyAll();
        this.flag = !this.flag;
    }
}

第一篇文章,感谢家人们的阅读

;原文链接:https://blog.csdn.net/ClearloveRelink/article/details/115656855
本站部分内容转载于网络,版权归原作者所有,转载之目的在于传播更多优秀技术内容,如有侵权请联系QQ/微信:153890879删除,谢谢!

推荐图文


随机推荐