11

我扫描了声明中的所有 java文档synchronized,以寻找这个问题的答案,但没有运气。

假设我有thread1, thread2,thread3试图同时运行以下代码。

 synchronized(lockObj) { 
     doSomething();
 }

假设thread1先到doSomething()thread2然后thread3它将阻塞并等待synchronized语句。

问题

  1. 释放锁时thread1,哪个线程会先被释放?
  2. 释放锁时适用的一般顺序规则是什么?
4

1 回答 1

21

1. 线程 2 或线程 3。没有保证:

同样,不应假设线程被授予监视器所有权的顺序或线程响应 notify 或 notifyAll 方法唤醒的顺序

http://docs.oracle.com/javase/1.5.0/docs/guide/vm/thread-priorities.html#general

2. Java 监视器(synchronized/await/notify/notifyAll)是不公平的。java 1.5 的同步原语通常有参数来强制公平。请注意,公平版本有相当大的性能损失,通常应该使用非公平版本:统计上,每个线程都将有机会运行,即使顺序没有严格执行。

使用由许多线程访问的公平锁的程序可能会显示出比使用默认设置的程序更低的整体吞吐量(即,更慢;通常要慢得多),但在获取锁和保证不会出现饥饿的情况下具有更小的差异。但是请注意,锁的公平性并不能保证线程调度的公平性。因此,使用公平锁的许多线程之一可能会连续多次获得它,而其他活动线程没有进展并且当前没有持有锁。另请注意,不定时的 tryLock 方法不遵守公平设置。如果锁可用,即使其他线程正在等待,它也会成功。

http://docs.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/locks/ReentrantLock.html#ReentrantLock%28boolean%29

于 2012-06-30T16:35:30.430 回答