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

时间:2012-09-28 06:45:45

标签: java multithreading synchronous

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

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

4 个答案:

答案 0 :(得分:4)

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

有关详细信息,请参阅JLS的section 14.19section 17.1,其中包括:

  

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

(强调我的。)

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

答案 1 :(得分:3)

  

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

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

  

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

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

让我们说ThreadAThreadB正在尝试同步块sbThreadB成功。现在,ThreadA将等到ThreadB完成。同时,假设ThreadC来自sb。它看到该块正在由某个线程运行,并在ThreadA的同一队列中等待。 ThreadB完成后,ThreadAThreadC有机会执行。

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

答案 2 :(得分:2)

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

来自JLS:

  

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

答案 3 :(得分:0)

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