干货-并发编程提高——线程状态(三)

  1. 首先要明确一点的是,java线程状态是指虚拟机层面暴露给我们的状态,操作系统(windows,linux等)的线程状态可能是N种,与java并不是一一对应的。但不管是N种还是M种都与java的六种所对应。为什么有时候java线程的优先级感觉不出来有什么效果,这也是因为java线程的优先级与操作系统线程的优先级并不是一一划等号的。

  1. 处于阻塞状态(Blocked)的线程,并不会占用CPU资源。但频繁的挂起与唤醒是很耗费CPU资源的。
  2. sleep方法wait方法都会释放此时占用的CPU资源。wait方法 / sleep方法皆响应中断方法且同为native方法sleep方法必须有参数。wait方法有两种一种有参一种无参。
  3. sleep方法无必须在同步方法或同步块儿中所执行,wait方法需要在同步块儿中使用。调用sleep方法的线程不会失去任何monitor对象的所有权,相反调用wait方法的线程会释放锁资源。wait方法是实例方法定义在Object类中,作用于对象本身。sleep方法定义在Thread类中,作用于当前线程。唤醒的方式也不同,被wait方法阻塞的线程需要其他线程调用对象的notify()/notifyAll()唤醒或者超时或中断interrupt()方法来唤醒。“睡眠的线程”的线程要么超时被唤醒,要么中断interrupt()方法来唤醒。
  4. notify()/notifyAll()/wait()配合使用。如果线程正等待未满足条件触发时即可wait(),待条件为真则调用notify() & notifyAll()方法唤醒那些线程重新开始,这些线程的状态会置为Runable。notify()方法是从等待中的线程中随机取一个去唤醒,而notifyAll()则是唤醒全部。
  5. 如何在代码中使用wait()方法? 答:正确的方法是在多线程共享的那个Object来使用wait()方法。在生产者消费者问题中,这个共享的Object就是那个缓冲区队列。对应的如果是同步静态方法,其wait的对象应该是当前对象.class.wait();
  6. 既然我们应该在synchronized的函数对象里调用wait(),那么哪个对象应该被synchronized呢? 答:希望上锁的对象就应该被synchronized。那个在多线程共享的对象。在生产者消费者问题中,应该被synchronized的就是那个缓冲队列。

// The standard idiom for calling the wait method in Java
synchronized (sharedObject) {
    while (condition) {
    sharedObject.wait();
        // (Releases lock, and reacquires on wakeup)
    }
    // do action based upon condition e.g. take or put into queue
}
  1. notify()/notifyAll()/wait()方法都需要在同步块儿中才能使用。
  2. wait()方法的常见使用场景就是在while循环体判断条件是否满足,如果不满足,那么就阻塞线程。不能用if,如果使用if的话,条件就被一次性的判断错过去了。循环要写在方法体的开始位置,避免因条件没有满足而污染业务逻辑。业界用语 - 虚假唤醒
  3. 想明白了一点,为什么要通过while循环+wait()去控制程序。是避免CPU的资源浪费,如果你没有获取资源的条件你就回去“睡会儿”,别占用CPU了。
  4. NotifyAll与Notify方法虽说是主观功能相似,实则还有些许区别。NotifyAll会引起“惊群效应”。一下子唤醒众多线程,此时的线程们皆由状态WAITTING变为RUNABLE,然而只会有一个线程最终获得执行权限,那么其他未获得执行时间的线程变“索然无味的”再次回到Wait状态。频繁挂起唤醒。
  5. 惊群效应(thundering herd)是指多进程(多线程)在同时阻塞等待同一个事件的时候(休眠状态),如果等待的这个事件发生,那么他就会唤醒等待的所有进程(或者线程),但是最终却只能有一个进程(线程)获得这个时间的“控制权”,对该事件进行处理,而其他进程(线程)获取“控制权”失败,只能重新进入休眠状态,这种现象和性能浪费就叫做惊群效应
  6. 依据上一条,那么什么时候用NotifyAll及Notify呢。我感觉CPU资源不是很紧张的时候,可以使用NotifyAll,资源紧张时用Notify。从整个程序的运转角度说,一次唤醒全部最终一个执行再把其他阻塞,与一次唤醒一个相比区别还是挺大的。
  • 16
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值