【狂神说Java】线程协作

发布时间:2022-07-05 发布网站:脚本宝典
脚本宝典收集整理的这篇文章主要介绍了【狂神说Java】线程协作脚本宝典觉得挺不错的,现在分享给大家,也给大家做个参考。

生产者消费者模式

【狂神说Java】线程协作

这是一个线程同步的问题,生产者和消费者共享同一个资,并且生产者和消费者之间互相依赖,互为条件。

  • 对于生产者,没有生产产品之前,要通知消费者等待,而生产生产了产品之后,又要马上通知消费者消费
  • 对于消费者,在消费之后,要通知生产者已经结束消费,需要生产新的产品以供消费
  • 在生产者消费者问题上,仅仅有synchronized是不够的
    • synchronized可阻止并发并更新同一个共享资源,实现了同步
    • synchronized不能用来实现不同线程之间的消息传递(通信)

【狂神说Java】线程协作

管程法

// 管程法 利用缓存区
public class testPC {
    public static void main(String[] args) {
        SynCatch con = new SynCatch();  // 缓存
        new Thread(new PRoductor(con)).start();
        new Thread(new Consumer(con)).start();
    }
}

// 生产者
class Productor implements Runnable {
    SynCatch syncatch;

    public Productor(SynCatch syncatch) {
        this.syncatch = syncatch;
    }

    @override
    public void run() {
        for (int i = 1; i <= 15; i++) {
            syncatch.push(new Product(i));
            System.out.println("生产了第" + i + "个产品");
        }
    }
}

// 消费者
class Consumer implements Runnable {
    SynCatch syncatch;

    public Consumer(SynCatch syncatch) {
        this.syncatch = syncatch;
    }

    @Override
    public void run() {
        for (int i = 1; i <= 15; i++) {
            System.out.println("消费了第" + syncatch.pull() + "个产品");
        }
    }

}


// 产品
class Product {
    int id; // 产品编号

    public Product(int id) {
        this.id = id;
    }
}

// 缓存区
class SynCatch {
    // 需要一个容器大小
    Product[] products = new Product[10];
    private int count = 0;

    // 生产者
    public synchronized void push(Product product) {
        // 如果容器满了
        if (count >= products.length) {
            // 通知消费
            try {
                this.waIT();// 线程等待,释放锁
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

        } else {
            products[count] = product;
            count++;
        }
        if (count >= 1)
            this.notifyAll();// 唤醒等待的线程
    }

    // 消费者
    public synchronized int pull() {
        // 如果容器满了
        if (count == 0) {
            // 等待生产
            try {
                this.notifyAll(); // 唤醒等待的线程
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        count--;
        Product product = products[count];
        return product.id;

    }
}

信号灯法

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){
                this.tv.play("节目:快乐大本营播放中");
                System.out.println();
            }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{
    
    boolean flag = true;  //  flag是信号灯,演员说话, 观众等待;观众观看 , 演员等待

    //说话
    String voice;

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

        //演员等待
        if (!flag){
            try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        System.out.println("表演了"+voice);
        this.voice = voice;

        //让观众观看
        this.notifyAll();
        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;
    }
}

判断一个标志位flag,如果为true,就让他等待、如果为false,就让他去通知另外一个人

脚本宝典总结

以上是脚本宝典为你收集整理的【狂神说Java】线程协作全部内容,希望文章能够帮你解决【狂神说Java】线程协作所遇到的问题。

如果觉得脚本宝典网站内容还不错,欢迎将脚本宝典推荐好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。