zoukankan      html  css  js  c++  java
  • Java 之多线程通信(等待/唤醒)

    多线程间通信: 多个线程在处理同一个资源, 但是任务却不同.

    等待/唤醒机制

    1. 涉及的方法
      • wait(): 让线程处于冻结状态, 被 wait() 的线程会被存储到线程池中
      • notify(): 唤醒线程池中的任意一个线程
      • notifyAll(): 唤醒线程池中所有的线程
    2. 这些方法必须定义在同步中, 因为这些方法是用于操作线程状态的方法, 必须要明确到底
      操作的是哪个锁上的线程.
    3. 为什么操作线程的方法 wait(), notify(), notifyAll() 定义在了 Object 类中?
      因为这些方法是监视方法, 监视器其实就是锁. 而锁可以是任意的对象, 任意对象都能调用的方法一定
      定义在 Object 类中.

    // 资源
    class Resource
    {
        String name;
        String sex;
        boolean flag = false;
    }
    
    // 输入线程
    class Input implements Runnable
    {
        Resource r;
    
        // 带参数的构造函数, 以确保输入和输出操作的是同一个资源
        Input(Resource r)
        {
            this.r = r;
        }
    
        public void run()
        {
            int x = 0;
            while(true)
            {
                synchronized(r)
                {
                    if(r.flag)
                        //该异常只能捕获, 不能抛出, 因为父类 Runnable 中 run() 方法没有异常
                        try{r.wait();}catch(InterruptedException e){}
                    if(x==0)
                    {
                        r.name = "mike";
                        r.sex = "nan";
                    }
                    else
                    {
                        r.name = "丽丽";
                        r.sex = "girlgirlgirl";
                    }
                    r.flag = true;
                    r.notify();
                }
                x = (x+1)%2; // 改变 x 的值, 获得不同的输入值
            }
        }
    }
    
    class Output implements Runnable
    {
        Resource r;
    
        // 带参数的构造函数, 确保输入和输出线程操作的是同一个资源
        Output(Resource r)
        {
            this.r = r;
        }
    
        public void run()
        {
            while(true)
            {
                synchronized(r) // 以资源对象作为锁, 输入线程和输出线程使用的为同一个锁
                {
                    if(!r.flag)
                        try{r.wait();}catch(InterruptedException e){}
                    System.out.println(r.name + "......" + r.sex);
                    r.flag = flase;
                    r.notify();
                }
            }
        }
    }
    
    class ResourceDemo
    {
        public static void main(String[] args)
        {
            // 创建资源
            Resource r = new Resource();
    
            // 创建任务
            Input in = new Input(r); // 使用带参数的构造函数初始化, 确保操作的为同一个资源 r
            Output out = new Output(r); //使用带参数的构造函数初始化, 确保操作的为同一个资源 r
    
            // 创建线程
            Thread t1 = new Thread(in);
            Thread t2 = new Thread(out);
            // 开启线程
            t1.start();
            t2.start();
    
        }
    }
    
    <--------------------分隔线--------------------------------->
    // 将属性私有化, 升级版
    class Resource
    {
        private String name;
        private String sex;
        private boolean flag = false;
    
        public synchronized void set(String name, String sex) //使用同步函数
        {
            if(flag)
                try{this.wait();}catch(InterruptedException e){}
            this.name = name;
            this.sex = sex;
            flag = true;
            this.notify(); // 这时候的锁是 this
        }
    
        public synchronized void out()
        {
            if(!flag)
                try{this.wait();}catch(InterruptedException e){}
            System.out.println(name+"....."+sex);
            flag = false;
            this.notify();
        }
    }
    
    class Input implements Runnable
    {
        Resource r;
    
        Input(Resource r)
        {
            this.r = r;
        }
    
        public void run()
        {
            int x = 0;
            while(true)
            {
                if(x==0)
                {
                    r.set("mike","nan");
                }
                else
                {
                    r.set("lili","nvnv");
                }
                x = (x+1)%2;
            }
        }
    }
    
    class Output implements Runnable
    {
        Resource r;
        Output(Resource r)
        {
            this.r = r;
        }
    
        public void run()
        {
            while(true)
            {
                r.out();
            }
        }
    }
    


    - [JavaSE 基础视频(毕向东)](https://www.bilibili.com/video/av3106510/)
  • 相关阅读:
    源代码的下载与编译
    Git使用入门
    搭建Android开发环境
    Android系统移植与驱动开发
    Android探索与驱动开发学与思(10)
    Android探索与驱动开发学与思(9)
    Android探索与驱动开发学与思(8)
    第七章
    第六章
    第五章
  • 原文地址:https://www.cnblogs.com/linkworld/p/7456746.html
Copyright © 2011-2022 走看看