0

当两个线程尝试访问同步块时会发生什么?

其中一个线程会在某处排队并稍后访问该线程,还是如果试用失败,该线程会放弃?

4

4 回答 4

4

假设您的意思是同步块,一个线程将设法获取监视器,而另一个线程将阻塞直到监视器被释放。

有关详细信息,请参阅JLS 的第 14.19 节第 17.1 节,包括:

同步语句(第 14.19 节)计算对对象的引用;然后它尝试在该对象的监视器上执行锁定操作,并且在锁定操作成功完成之前不会继续进行。执行完锁定操作后,将执行同步语句的主体。如果主体的执行完成,无论是正常的还是突然的,都会在同一个监视器上自动执行解锁操作。

(强调我的。)

如果您需要任何其他语义 - 例如超时 - 您应该使用java.util.concurrent.locks包中的一种类型,以便您可以使用 和 等tryLock()方法tryLock(long time, TimeUnit unit)

于 2012-09-28T06:47:55.960 回答
3

其中一个线程会在某处排队吗

是的,它在 JVM 中排队等待直到 runnig 线程释放锁。

如果试用失败,线程会放弃吗

不,它会一直尝试直到 JVM 还活着。但在另一个线程运行同步代码期间不尝试。(除非指定超时)

可以说ThreadA并且ThreadB正在尝试同步块sbThreadB成功。现在,ThreadA将等到ThreadB完成。同时,假设ThreadC来了sb。它看到该块正在由某个线程运行并在同一个队列中等待ThreadA。当ThreadB完成ThreadAThreadC有机会执行时。

因此,从技术上讲,它不是队列,而是类似的数据结构。

于 2012-09-28T06:48:46.257 回答
2

其中一个会在必要时永远等待(例如第一个线程执行无限循环),尽管那将是一个相当糟糕的设计。代码执行同步没有超时。

来自 JLS:

同步语句代表执行线程获取互斥锁,执行块,然后释放锁。当执行线程拥有锁时,没有其他线程可以获取锁。

于 2012-09-28T06:47:00.283 回答
0

如果synchronized块正在由另一个线程执行,则两个线程都将等待。否则,将允许一个线程工作,而另一个线程将等待第一个线程完成其工作。

于 2012-09-28T06:50:14.433 回答