zoukankan      html  css  js  c++  java
  • 线程通信——wait(),notify(),notifyAll()

    wait():执行此方法,当前线程就会进入阻塞状态,并释放同步监视器(也可以理解成所持有的锁)

    notify():执行此方法,会唤醒wait的一个线程,如果有多个线程被wait,就会唤醒优先级高的,如果优先级一致就随机唤醒一个

    notifyAll():执行该方法,就会唤醒所有被wait的线程

    注意:

      1、wait()、notify()、notifyAll()三个方法必须使用在同步代码块或同步方法中

      2、wait()、notify()、notifyAll()三个方法的调用者必须是同步代码块或同步方法中的同步监视器,否则会出现IllegalMonitorStateException异常

      3、wait()、notify()、notifyAll()三个方法是定义在java.lang.Object类中。

        原因:同步监视器可以使用任意类的对象充当,为了保证任何对象都能调用这三个方法,就必须将其放在Object中(Object是所有类的父类)

       notify()方法会唤醒对象条件队列中等待的某个线程,但是这个唤醒是无序的(和VM调度,OS调度有关,甚至底层是随机选取一个,更

    甚至就是队列中的第一个)。 而如果,条件队列不断有新的线程进入,或者在唤醒的那一刻,刚好有其他线程抢入,那都可能导致某个运气不好的线程

    迟迟不能被唤醒。 对这个线程来说,就是进入一种“饥饿”的状态,甚至还会有“饿死”的风险。

    进程通信可能出现的问题——饥饿问题    

    在Java中,通常有以下几种情况导致饥饿:

    1. CPU被高优先级的线程完全占用(打满),而导致低优先级的线程一直没有机会获得CPU
    2.   解决方法:可以为每个线程单独设置一个优先级。 高优先级的线程可以获得更多CPU时间。 在Java中可以设置1~10个等级的优先级。 实际上,这个优先级等级依赖于具体的操作系统。 对于一般应用来说,保持默认的优先级,就可以了。
    3. synchronized同步块导致某个线程频繁重入(偏向锁,以及OS调度策略,导致已经获得monitor锁的线程有更多的机会再次获得锁),而导致其他线程只能阻塞等待
    4. 某个线程在某个对象的条件队列上等待(wait()),而其他线程不断的抢入。
  • 相关阅读:
    JavaScript如何获取一个元素的样式信息
    Linux服务器命令行操作(小白专用)
    Linux云服务器搭建node环境
    C++ new和delete运算符简介
    C++中free()与delete的区别
    VS2017+Qt开发时打开命令调试窗口
    opencv4.2版本遇到CV_MINMAX未声明标识符
    CUDA 数据传输
    uchar 存为8位/16位图像(QImage)
    Qt Creator删除toolbar中多余的“分隔符”
  • 原文地址:https://www.cnblogs.com/xing-29391/p/14113260.html
Copyright © 2011-2022 走看看