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

    线程通信

    线程的通信就是一个数据可以让两个线程轮流打印 你打印一下 我打印一下 

    线程的通信需要用到 wait() notify() 和 notifyAll()方法来使线程进行通信

    通信方法:

    wait() : 一旦执行此方法 当前线程就进入阻塞状态,并释放同步监视器(锁)
    
    notify(): 一旦执行此方法,就会被唤醒的wait线程,如果有多个线程被wait就会唤醒优先级高的
    
    notifuAll(): 一旦执行此方法释放所有被wait()方法阻塞的线程

    说明:

    说明:
       1: wait() notify() notifyAll() 必须使用在同步代码块或者同步范方法中
       2: 这三个方法必须都是同一个同步监视器调用
    

    eg:

    class ThreadTon implements  Runnable{
        private  int num = 1;
        @Override
        public void run() {
            while (true){
                synchronized(this){
                    notify(); // 让上一个阻塞的线程放开
                    if(num < 100){
                        try {
    
                            Thread.sleep(100);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        System.out.println(Thread.currentThread().getName()+" : "+num);
                        num ++;
    
    
                        try {
                            ///调用方法是进来的线程进入阻塞状态, 执行wait会释放锁 一个线程执行了wait另一个就拿到了执行了
                            wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }else{
                        break;
                    }
                }
    
            }
        }
    }

    面试题:

     面试题: sleep() 和wait()异同
      
    
       相同:一旦执行都会使线程进入阻塞状态
    
       不同点:
                1: 两个方法的声明位置不同 Thread中声明sleep() Object中声明wait()
                2: 调用的范围: sleep随时可以用, wait()必须使用在同步代码或者同步方法中
                3: 是否释放同步监视器: 如果两个方法都是用在同步代码块和同步方法中 sleep()不会释放锁,wait()会释放锁
    sleep和wait异同点

    线程通信的经典例题: 生产者消费者

    生产者(Productor)将产品交给店员(Clerk),而消费者(Customer)从店员处 取走产品,
    店员一次只能持有固定数量的产品(比如:20),
    如果生产者试图 生产更多的产品,店员会叫生产者停一下,
    如果店中有空位放产品了再通 知生产者继续生产;如果店中没有产品了,
    店员会告诉消费者等一下,如 果店中有产品了再通知消费者来取走产品。

    首先我们要分析具体的信息

    分析:
      1; 是否有多线程问题? 是,生产者线程, 消费者线程
      2: 是否有共享数据? 店员(或者产品)
      3: 如何解决线程的安全问题? 同步机制三中方法
      4: 是否涉及线程的通信
    public class ProductTestOne {
        public static void main(String[] args) {
            ClerkOne clerkOne = new ClerkOne();
            Consum c1 = new Consum(clerkOne);
    
            Produc p1 = new Produc(clerkOne);
            p1.start();
            c1.start();
    
        }
    }
    
    
    
    class ClerkOne{  // 商品
    
    
        private  int count = 0; // 记录商品的数量
    
    
        public synchronized  void consumPro() {  // 消费方法
    
            if(count > 0){
                notify();  // 释放对方的线程
                System.out.println(Thread.currentThread().getName() + " 开始消费第几个 : "+count);
                count --;
            }else{ // 等待
                try {
                    wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    
        public synchronized void producPro() {  // 生产
    
            if(count < 20){
                count ++;
                System.out.println(Thread.currentThread().getName() +"  开始生产第: "+count);
                notify();
            }else{ // 等待
                try {
                    wait();  // 线程通信
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    
    class Consum extends Thread{  // 消费者
        private  ClerkOne clerkOne;
    
        
        public Consum(ClerkOne clerkOne){
            this.clerkOne = clerkOne;
        }
    
        @Override
        public void run() {
            System.out.println("消费者开始消费");
            while (true){
                try {
                    Thread.sleep(10);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                clerkOne.consumPro();
            }
        }
    }
    
    class Produc extends  Thread{  // 生产者
        private  ClerkOne clerkOne;
        
        public Produc (ClerkOne clerkOne){
            this.clerkOne = clerkOne;
        }
    
        @Override
        public void run() {
            System.out.println("生产者开始生产");
            while (true){  // sleep下 给生产消费留下余地
                try {
                    Thread.sleep(10);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                clerkOne.producPro();
            }
        }
    }
    生产者消费者解答

    .

  • 相关阅读:
    文本建模、文本分类相关开源项目推荐(Pytorch实现)
    自然语言推断(NLI)、文本相似度相关开源项目推荐(Pytorch 实现)
    20155312 张竞予 Exp9 Web安全基础
    20155312 张竞予 Exp 8 Web基础
    20155312 张竞予 Exp7 网络欺诈防范
    20155312 张竞予 Exp6 信息搜集与漏洞扫描
    20155312 张竞予 Exp5 MSF基础应用
    20155312 张竞予 Exp4 恶意代码分析
    20155312 张竞予 Exp3 免杀原理与实践
    20155312 张竞予 Exp2 后门原理与实践
  • 原文地址:https://www.cnblogs.com/zhaoyunlong/p/11881890.html
Copyright © 2011-2022 走看看