美文网首页
高并发(6)- 多线程之间的协作

高并发(6)- 多线程之间的协作

作者: 残冬十九 | 来源:发表于2020-03-30 22:13 被阅读0次

    @[TOC](高并发(6)- 多线程之间的协作)

    前言

        上篇文章讲解了线程之间的共享。本篇文章就来讲讲线程之间的协作。
        毕竟java线程是协作式,而非抢占式的。
    

    线程的协作

    一、什么是线程的协作
      顾名思义,线程的协作就是多个线程之间的协作。比如快递这个场景,一个线程负责处理快递的物流信息更新,什么时候快递到了什么的地区,一个线程负责快递的事实信息,当快递到了某个地点,这个时候通知负责物流更新的线程物流进度有变化,你快更新,这个就是线程的协作。
    二、线程协作方式
      wait、notify、notifyAll三种方法来实现,分别是等待,唤醒和全部唤醒方法。
    1.waiti
      wait是等待方法,执行wait方法会释放当前锁,让出cpu,进入等待状态。只要notify/notifyAll()方法被执行的时候,才会唤醒一个或多个正处于等待的线程,然后继续往下执行,执行完synchronized 代码块的或者遇到了wait的时候,会再次释放锁。 
    2.notify
      notify是唤醒方法,可以唤醒当前线程,从wait状态回到就绪状态,重新参与cpu的抢夺之中。
    3.notifyAll
      notifyAll也是唤醒方法,但唤醒的是所有线程,使所有的wait状态的线程重新回到就到就绪状态,同样参与cpu的争夺。
    三、代码

    /**
     * @version 1.0
     * @Description 快递对象
     * @Author wb.yang
     */
    public class Express {
    
    
        public final static String CITY = "HeNan";
        /**
         * 快递地址
         */
        private String site;
    
        public Express(String site) {
            this.site = site;
        }
    
    
        /**
         * 地点数有变化的时候,通知处于wait状态的,进行公里变化的业务处理
         */
        public synchronized void changeSite() {
            this.site = "BeiJing";
            notifyAll();
        }
    
        public synchronized void waitSite() {
            while (CITY.equals(this.site)) {
                try {
                    System.out.println("检查地点线程[" + Thread.currentThread().getId()
                            + "] 等待中");
                    wait();
                    System.out.println("检查地点线程[" + Thread.currentThread().getId()
                            + "] 被通知了");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            System.out.println("当前地点是" + this.site + "我要通知用户");
        }
    }
    
    

    上面的代码可以看出,我们定义了一个快递的对象,包含了快递当前地点,还有一个等待地点变化的方法,在本方法中等待地点变化,实行我们的业务逻辑,然后有一个变化地点的方法,变换快递地点并调用notifyAll方法,唤醒等待的线程。

    /**
     * @version 1.0
     * @Description 线程协作demo
     * @Author wb.yang
     */
    public class SynergyDemo {
    
        private static Express express = new Express(Express.CITY);
    
    
        private static class CheckSite extends Thread {
            @Override
            public void run() {
                express.waitSite();
            }
        }
    
        public static void main(String[] args) throws InterruptedException {
            new CheckSite().start();
            Thread.sleep(5000);
            //快递地点更新
            System.out.println("快递地点更新");
            express.changeSite();
        }
    }
    
    

    这个代码是我们执行线程的方法,main方法中,先运行了线程的run方法,进行快递地点变化的等待,然后休眠五秒后,调用快递地点变化的方法,唤醒等待的线程,执行接下来物流更新的逻辑。


    代码运行结果

    从结果中可以看出,先是线程检查地点,然后进入等待中,随后开始更新快递地点,然后线程结束等待,输出最新的物流信息。
    四、总结
      通过使用wait方法使线程进入等待状态,然后释放锁,让出cpu,通过notify和notifyAll来唤醒线程,是等待状态重新变为就绪状态,开始抢夺cpu,然后执行业务逻辑。

    相关文章

      网友评论

          本文标题:高并发(6)- 多线程之间的协作

          本文链接:https://www.haomeiwen.com/subject/grwbuhtx.html