• 《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

  • 相关阅读:
    学习笔记4
    学习笔记3
    学习笔记2
    学习笔记1
    MySQL 随笔总结
    java1-4
    java1-3
    java1-2
    java 1-1
    Mysql 基础
  • 原文地址:https://www.cnblogs.com/thewindkee/p/12873130.html
Copyright © 2020-2023  润新知