当两个线程试图访问同步块时会发生什么?
其中一个线程是否会在某处排队并稍后访问该线程,或者如果试用失败,线程是否会放弃?
答案 0 :(得分:4)
假设您的意思是 synchronized 块,一个线程将设法获取监视器,另一个线程将阻塞,直到监视器被释放。
有关详细信息,请参阅JLS的section 14.19和section 17.1,其中包括:
synchronized语句(第14.19节)计算对象的引用;然后,它会尝试在该对象的监视器上执行锁定操作,并且在锁定操作成功完成之前不会继续进行。执行锁定操作后,将执行synchronized语句的主体。如果正常或突然完成正文的执行,则会在同一监视器上自动执行解锁操作。
(强调我的。)
如果您需要任何其他语义 - 例如超时 - 您应该使用java.util.concurrent.locks
包中的某种类型,以便您可以使用tryLock()
和tryLock(long time, TimeUnit unit)
等方法。
答案 1 :(得分:3)
其中一个线程是否会在某处排队
是的,它在JVM中排队等待,直到runnig线程释放锁。
如果试用失败,线程会放弃
不,它一直在尝试直到JVM还活着。但是在运行同步代码的另一个线程期间没有尝试。(除非指定超时)
让我们说ThreadA
和ThreadB
正在尝试同步块sb
和ThreadB
成功。现在,ThreadA
将等到ThreadB
完成。同时,假设ThreadC
来自sb
。它看到该块正在由某个线程运行,并在ThreadA
的同一队列中等待。 ThreadB
完成后,ThreadA
或ThreadC
有机会执行。
因此,从技术上讲,它不是一个队列,而是一个类似的数据结构。
答案 2 :(得分:2)
其中一个将在必要时永远等待(例如第一个执行无限循环的线程),尽管这将是一个相当糟糕的设计。代码执行同步没有超时。
来自JLS:
synchronized语句代表执行线程获取互斥锁,执行块,然后释放锁。当执行线程拥有锁时,没有其他线程可以获得锁。
答案 3 :(得分:0)
如果另一个线程正在执行synchronized
块,则两个线程都将等待。否则,将允许一个线程继续工作,另一个线程将等到第一个线程完成其工作。