830.怎么唤醒⼀个阻塞的线程?

  1. 如果线程是因为调⽤了wait()、sleep()或者join()⽅法⽽导致的阻塞;
    1. suspend与resume
      Java废弃 suspend() 去挂起线程的原因,是因为 suspend() 在导致线程暂停的同时,并不会去释放任何锁资源。其他线程都⽆法访问被它占⽤的锁。直到对应的线程执⾏ resume() ⽅法后,被挂起的线程才能继续,从⽽其它被阻塞在这个锁的线程才可以继续执⾏。
      但是,如果 resume() 操作出现在 suspend() 之前执⾏,那么线程将⼀直处于挂起状态,同时⼀直占⽤锁,这就产⽣了死锁。⽽且,对于被挂起的线程,它的线程状态居然还是 Runnable。
    2. wait与notify
      wait与notify必须配合synchronized使⽤,因为调⽤之前必须持有锁,wait会⽴即释放锁,notify则是同步块执⾏完了才释放
    3. await与singal
      Condition类提供,⽽Condition对象由new ReentLock().newCondition()获得,与wait和notify相同,因为使⽤Lock锁后⽆法使⽤wait⽅法
    4. park与unpark
      LockSupport是⼀个⾮常⽅便实⽤的线程阻塞⼯具,它可以在线程任意位置让线程阻塞。和Thread.suspenf()相⽐,它弥补了由于resume()在前发⽣,导致线程⽆法继续执⾏的情况。和Object.wait()相⽐,它不需要先获得某个对象的锁,也不会抛出IException异常。可以唤醒指定线程。
  2. 如果线程遇到了IO阻塞,⽆能为⼒,因为IO是操作系统实现的,Java代码并没有办法直接接触到操作系统。