zoukankan      html  css  js  c++  java
  • 线程通信

    线程间通信的方法:


    经典模型:生产者消费者模式

    1.管程法:

    package threadStudy;
    
    public class ThreadCommunicate {
        public static void main(String[] args) {
            Buffer buffer = new Buffer();
            new Producer(buffer).start();
            new Consumer(buffer).start();
        }
    }
    
    class Producer extends Thread {
        Buffer buffer;
        public Producer(Buffer buffer) {
            this.buffer = buffer;
        }
        @Override
        public void run() {
            for (int i = 0; i < 20; i++) {
                System.out.println("生产的第" + i + "杯奶茶" );
                buffer.add(new MilkTea(i));
            }
            
        }
    }
    
    class Consumer extends Thread {
        Buffer buffer;
        public Consumer(Buffer buffer) {
            this.buffer = buffer;
        }
        @Override
        public void run() {
            for (int i = 0; i < 20; i++) {
                System.out.println("消费的第" + i + "杯奶茶" );
                buffer.pop();
            }
        }
    }
    
    //缓冲区
    class Buffer {
        MilkTea[] milkTea = new MilkTea[10];
        private int count = 0;
    
        public synchronized void add(MilkTea m) {
            //缓冲区满了  停止生产
            if(count==milkTea.length) {
                try {
                    this.wait();
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            milkTea[count] = m;
            count++;
            this.notifyAll();
        }
    
        public synchronized MilkTea pop() {
            //缓冲区无东西  停止消费
            if(count==0) {
                try {
                    this.wait();
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            count--;
            MilkTea temp = milkTea[count];
            this.notifyAll();
            return temp;
        }
    }
    
    class MilkTea {
        int id;
        public MilkTea(int id) {
            this.id = id;
        }
        
    }
    输出:
    生产的第0杯奶茶
    消费的第0杯奶茶
    消费的第1杯奶茶
    生产的第1杯奶茶
    生产的第2杯奶茶
    消费的第2杯奶茶
    生产的第3杯奶茶
    消费的第3杯奶茶
    消费的第4杯奶茶
    生产的第4杯奶茶
    生产的第5杯奶茶
    生产的第6杯奶茶
    生产的第7杯奶茶
    生产的第8杯奶茶
    生产的第9杯奶茶
    生产的第10杯奶茶
    生产的第11杯奶茶
    生产的第12杯奶茶
    生产的第13杯奶茶
    生产的第14杯奶茶
    生产的第15杯奶茶
    消费的第5杯奶茶
    消费的第6杯奶茶
    生产的第16杯奶茶
    消费的第7杯奶茶
    消费的第8杯奶茶
    生产的第17杯奶茶
    消费的第9杯奶茶
    生产的第18杯奶茶
    消费的第10杯奶茶
    生产的第19杯奶茶
    消费的第11杯奶茶
    消费的第12杯奶茶
    消费的第13杯奶茶
    消费的第14杯奶茶
    消费的第15杯奶茶
    消费的第16杯奶茶
    消费的第17杯奶茶
    消费的第18杯奶茶
    消费的第19杯奶茶
    View Code

    2.信号灯法

    package threadStudy;
    
    public class ThreadCommunicate2 {
        public static void main(String[] args) {
            Song song = new Song();
            new Actor(song).start();
            new Audience(song).start();
        }
    }
    
    class Actor extends Thread{
        Song song;
        
        public Actor(Song song) {
            this.song = song;
        }
    
        @Override
        public void run() {
            for (int i = 0; i < 10; i++) {
                if(i%2==0) {
                    song.sing("发如雪");
                }
                else {
                    song.sing("青花瓷");
                }
            }
        }
    }
    
    class Audience extends Thread{
        Song song;
        public Audience(Song song) {
            this.song = song;
        }
        
        
        @Override
        public void run() {
            for (int i = 0; i < 10; i++) {
                song.listen();
            }
            
        }
    }
    
    class Song{
        private String name;
        //true 表示演员已经唱好了  false表示还未唱好 即还不可以挺
        private boolean flag = false;
        
        public synchronized void sing(String name) {
            if(flag) {
                try {
                    this.wait();
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            
            this.name = name;
            System.out.println("周杰伦唱了:"+name);
            this.notifyAll();
            flag = !flag;
        }
        
        public synchronized void listen() {
            if(!flag) {
                try {
                    this.wait();
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            System.out.println("我听了:"+this.name);
            this.notifyAll();
            flag = !flag;
        }
    }
    输出:
    周杰伦唱了:发如雪
    我听了:发如雪
    周杰伦唱了:青花瓷
    我听了:青花瓷
    周杰伦唱了:发如雪
    我听了:发如雪
    周杰伦唱了:青花瓷
    我听了:青花瓷
    周杰伦唱了:发如雪
    我听了:发如雪
    周杰伦唱了:青花瓷
    我听了:青花瓷
    周杰伦唱了:发如雪
    我听了:发如雪
    周杰伦唱了:青花瓷
    我听了:青花瓷
    周杰伦唱了:发如雪
    我听了:发如雪
    周杰伦唱了:青花瓷
    我听了:青花瓷
    View Code
  • 相关阅读:
    如何将cordova导入Android studio,只需两步即可
    Cordova 教程 学习步骤-从零基础开始
    特效插件
    jq 命名空间
    input聚焦后光标移动至末尾
    时间常用api
    jq 便捷api jq 常用 api jq 快捷 api
    键盘事件
    创建爬网规则
    SharePoint 2013 本地开发解决方案以及程调试(真的可以)
  • 原文地址:https://www.cnblogs.com/ustc-anmin/p/11012857.html
Copyright © 2011-2022 走看看