Java线程阻塞

Java能使得线程阻塞的基础工具(其余能阻塞线程的方法都是基于它们的)有4种:

  1. synchronized关键字
    控制对资源的同步访问,如果另一个线程已经持有了对象锁,那么尝试获取锁的线程将被阻塞,并且线程的状态会变为BLOCKED
  2. Object.wait:
    当线程调用wait()方法时,它必须持有该对象的锁。wait()会释放锁。这时线程的状态将变为WAITING(或在使用wait(long timeout)时变为TIMED_WAITING)。线程会保持等待状态直到被notify()或notifyAll()唤醒,或是等待超时。
  3. LockSupport.park和LockSupport.parkNanos:
    LockSupport.park()和相关方法使线程进入阻塞状态,直到它接收到一个“许可”(从其他线程调用unpark()),或者有其他中断。在使用LockSupport阻塞时,线程的状态是WAITINGTIMED_WAITING(如果使用了parkNanos()或parkUntil()方法的话)。
  4. Thread.sleep(long millis)

其中Thread.sleep(long millis)是打酱油的,不涉及线程的同步或协作,一般只用于示例、教学代码或测试代码中。所以我们主要关注另外3种即可。

为啥有了Object.wait()还需要LockSupport.park()呢?
因为Object.wait()只能在synchronized同步块中使用,而LockSupport.park()则更灵活,没有必须在同步块中使用的限制条件。

Lock、Condition、BlockingQueue、Semaphore、CountDownLatch、CyclicBarrier等都是使用LockSupport.park()来阻塞线程。


synchronized、Object.wait()和Lock、Condition.await()这两套怎么选?
阻塞在一个条件上,选synchronized、Object.wait(),代码写起来更简洁。
阻塞在多个条件上,没得选,必须用Lock、Condition.await()。

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容