zoukankan      html  css  js  c++  java
  • 《Java高并发编程详解-多线程架构与设计》线程间的通信

    摘自《Java高并发编程详解-多线程架构与设计》第五章

    同步、异步、阻塞、非阻塞概念

    同步和异步
    结果的通知机制。自己问还是别人通知。
    同步:主动等待结果的返回。如阻塞等待,轮询(同步非阻塞)。
    异步:被动等待结果的返回。如 消息回调。

    阻塞和非阻塞
    结果返回以前,调用方的状态。等还是不等。
    阻塞:结果返回以前,什么也不干。

    非阻塞:在结果返回以前,可以先做一些其他事情。

    Monitor锁

    下面所说的获取monitor锁都是指的先使用synchronized获取对象锁
    不应该叫synchronized(mutex)为锁,而应该是某个线程获取了与mutex关联的monitor锁。

    wait 与 notify

    wait 理解成线程在等待直到该对象可用。(被notify后就不再等待)

    notify理解成线程通知该对象可用。

    使用wait的注意事项

    1. wait必须在同步方法中使用,因为wait必须由拥有monitor(已用synchronize获取锁)的线程调用。

    2. wait可以被中断,为了防止wait被interrupt唤醒,wait方法需要在循环中使用。

    3. 使用wait后自动释放线程对应的锁。–release ownership of this monitor

    4. wait会等待直到其他线程调用notify/notifyAll唤醒。–waits until anthoer thread notifies threads waiting on this object’s monitor to wake up…

    5. 被notify/notifyAll唤醒后会重新获得锁的拥有权,然后接着执行。–re-obtain ownership of the monitor and resumes execution.

    6. 线程调用wait后, 会加入与之对应的wait set.每个对象都有一个与之对应的wait set.使用notify会将其中一个弹出,notifyAll弹出所有线程。(C5.3.2)

      Causes the current thread to wait until another thread invokes the
      * {@link java.lang.Object#notify()} method or the
      * {@link java.lang.Object#notifyAll()} method for this object.
      * In other words, this method behaves exactly as if it simply
      * performs the call {@code wait(0)}.
      *


      * The current thread must own this object’s monitor. The thread
      * releases ownership of this monitor and waits until another thread
      * notifies threads waiting on this object’s monitor to wake up
      * either through a call to the {@code notify} method or the
      * {@code notifyAll} method. The thread then waits until it can
      * re-obtain ownership of the monitor and resumes execution.
      * As in the one argument version, interrupts and spurious wakeups are
      * possible, and this method should always be used in a loop:
      * synchronized (obj) {
      * while (<condition does not hold>)
      * obj.wait();
      * … // Perform action appropriate to condition
      * }
      * This method should only be called by a thread that is the owner
      * of this object’s monitor. See the {@code notify} method for a
      * description of the ways in which a thread can become the owner of a monitor.

    使用notify的注意

    1. 必须在同步方法中使用wait、notify,因为他们的使用前提都是持有monitor所有权。

    2. 同步代码块的monitor必须与执行 wait 、notify的对象一致,也就是说对哪个对象同步,才能调用那个对象的 wait、notify。

    例子:

    若不是用的notifyAll, 则不能用于多线程环境

    在这里插入图片描述
    在这里插入图片描述
    while而不是if中调用wait!否则一旦被interrupt,会跳过判断继续执行。如
    在这里插入图片描述

    测试主动interrupt对if中使用wait的影响

    这里主动interrupt,可见当producer被interrupt后,producer就略过了判断,继续添加了一个event

    test interrupt

    wait与sleep的

    • 相同:
      使线程阻塞
      可以中断
    • 不同:
      wait是Object的方法,sleep是Thread的
      wait必须要在同步代码块中执行。
      wait会释放monitor的锁,sleep不会
      sleep短暂休眠后会退出阻塞?(TODO)wait(没有指定时间的话)必须被中断才会退出阻塞。

    synchronized的缺点

    1. 无法中断
      synchronized不像sleep和wait那样,可以被中断。

    2. 没有等待时间
      其他线程获取锁的拥有权必须要等待锁的拥有者(线程)释放后才能执行。

    利用wait、notify实现可中断的BooleanLock

    p96-104
    一旦从wait中被唤醒则有机会检查lock是否为false,为false则修改获取锁的线程cureentLockThread为自己,并设置lock为true.防止其他线程继续争抢。
    如果wait超时会报错,notify后超时 也主动抛错。

    关键代码

    在这里插入图片描述

    从wait中被notify或者等待超时后,会因为while(locked),locked为false,说明没有线程持有monitor的拥有权,因此跳出while设置locked=true;this.currentThread=currentThread();
    在这里插入图片描述
    优化,超时后清除blackList
    在这里插入图片描述

    发布于2019年7月7日 16:40:43

  • 相关阅读:
    剑指Offer-11.二进制中1的个数(C++/Java)
    剑指Offer-10.矩形覆盖(C++/Java)
    剑指Offer-9.变态跳台阶(C++/Java)
    UVA 1608 Non-boring sequence 不无聊的序列(分治,中途相遇)
    UVA1607 Gates 与非门电路 (二分)
    UVA 1451 Average平均值 (数形结合,斜率优化)
    UVA 1471 Defense Lines 防线 (LIS变形)
    UVA 1606 Amphiphilic Carbon Molecules 两亲性分子 (极角排序或叉积,扫描法)
    UVA 11134 FabledRooks 传说中的车 (问题分解)
    UVA 1152 4 Values Whose Sum is Zero 和为0的4个值 (中途相遇)
  • 原文地址:https://www.cnblogs.com/thewindkee/p/12873130.html
Copyright © 2011-2022 走看看