• 线程之间如何通信


    1、利用缓冲区解决:管程法

    // 生产者、消费者、产品、缓冲区
    public class TestPC {
        public static void main(String[] args) {
            SynContainer container = new SynContainer();
            new Production(container).start();
            new Consumer(container).start();
        }
    }
    
    // 生产者
    class Production extends Thread {
        SynContainer container;
    
        public Production(SynContainer container) {
            this.container = container;
        }
    
        // 生产
        @Override
        public void run() {
            for (int i = 0; i < 100; i++) {
                container.push(new Chicken(i));
                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++) {
                System.out.println("消费了---->>" + container.pop().id + "只鸡");
    
            }
        }
    }
    
    // 产品
    class Chicken {
        int id; // 编号
    
        public Chicken(int id) {
            this.id = id;
        }
    }
    
    // 缓存区
    class SynContainer {
    
        // 需要一个容器大小
        Chicken[] chickens = new Chicken[10];
        // 容器计数器
        int count = 0;
    
        // 生产者放入产品
        public synchronized void push(Chicken chicken) {
            // 如果容器满了,需要等待消费者消费
            if (count == chickens.length) {
                // 通知消费者消费,生产者等待
                try {
                    this.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
    
            }
            // 如果没有满就丢入产品
            chickens[count] = chicken;
            count++;
            //通知消费者消费
            this.notifyAll();
        }
    
        // 消费者消费产品
        public synchronized Chicken pop() {
            // 判断能否消费
            if (count == 0) {
                // 等待生产者生产,消费者等待
                try {
                    this.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            // 如果可以消费
            count--;
            Chicken chicken = chickens[count];
            // 通知生产者 吃完了
            this.notifyAll();
            return chicken;
        }
    }
    

    2、利用标志位解决:信号灯法

    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("快乐大本营播放中..");
                } 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++) {
                this.tv.watch();
            }
        }
    }
    
    // 产品-->节目
    
    class TV extends Thread {
    
        // 演员表演,关众等待 T
        // 关众观看,演员等待 F
    
        String video; // 节目
        boolean flag = true; // 标记
    
        // 表演
        public synchronized void play(String video) {
            if (!flag) {
                // 演员等待
                try {
                    this.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            System.out.println("演员表演了:" + video);
            // 通知关众观看
            this.notifyAll(); // 通知唤醒
            this.video = video;
            this.flag = !this.flag;
        }
    
        // 观看
        public synchronized void watch() {
            if (flag) {
                try {
                    this.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            System.out.println("观看了:"+video);
    
            // 通知演员表演
            this.notifyAll();
            this.flag = !this.flag;
        }
    }
    
    本人写博文完全是为了自己去巩固一些知识点,做笔记,但同时也希望可以帮助到大家,如果有什么不好的地方,也希望大家见谅!希望大家一起进步!!
  • 相关阅读:
    solr dataimport 数据导入源码分析(九)
    正确理解ThreadLocal
    solr dataimport 数据导入源码分析(六)
    solr dataimport 数据导入源码分析(七)
    solr dataimport 数据导入源码分析(八)
    solr dataimport 数据导入源码分析(一)
    solr dataimport 数据导入源码分析(五)
    OpenGL光照、键盘
    OpenGL着色
    OpenGL纹理映射
  • 原文地址:https://www.cnblogs.com/exce-ben/p/14332664.html
Copyright © 2020-2023  润新知