tryLock和lock.tryLock的行为(超时,单位)

时间:2017-03-14 18:32:41

标签: java multithreading concurrency locking

我对ReentrantLock的tryLock和lock.tryLock(超时,单位)函数几乎没有疑问。

  1. 如果两个线程通过调用lock.tryLock(timeout,unit)等待锁定将会发生什么。当两个线程仍在等待时它们被释放(它们的超时尚未完成)。我的问题是哪个线程会被锁定?另一个等待线程会发生什么? 例如:
     在t = 0 th1拥有锁定
     在t = 1 th2时,调用lock.tryLock(超时,单位)4秒  在t = 2 th3时,调用lock.tryLock(超时,单位)3秒钟  在t = 3 th1释放锁定
     我认为,如果锁定是公平的,th2将获得锁定。我是对的吗?  如果锁不公平将会发生什么。另一个线程会发生什么,该线程是否会等待剩余时间?

  2. 哪个方法优先,定时tryLock或untime tryLock 例如
    在t = 0 th1拥有锁定
    在t = 1 th2时,调用lock.tryLock(超时,单位)2秒 在t = 2 th1释放锁同时某个线程th3调用lock.tryLock()哪个线程th1或th3会被锁定?

    th *代表一个主题。

2 个答案:

答案 0 :(得分:0)

  1. 首先在公平排序poicy下调用lock.tryLock(timeout,unit)。根据 tryLock - Java Doc
  2.   

    获取锁定,如果它没有被另一个线程持有并立即返回值为true,则将锁定保持计数设置为1。 如果此锁定已设置为使用公平排序策略,则在任何其他线程等待锁定时,将不会获取可用锁定。这与tryLock()方法形成对比。如果你想要一个允许在公平锁定上进行插入的定时tryLock,那么将定时和非定时表单组合在一起:   if (lock.tryLock() || lock.tryLock(timeout, unit) ) { ... }

    1. th3将拥有锁
    2.   

      获取锁定,如果它没有被另一个线程持有并立即返回值为true,则将锁定保持计数设置为1。 即使已将此锁定设置为使用公平排序策略,对tryLock()的调用也会立即获取锁定(如果可用),无论其他线程当前是否正在等待锁定。这"闯入"行为在某些情况下可能有用,即使它违反了公平性。如果您想要遵守此锁的公平性设置,请使用几乎相同的tryLock(0,TimeUnit.SECONDS)(它还会检测中断)。

答案 1 :(得分:0)

  

我认为如果锁定是公平的,th2将获得锁定。我是对的吗?

是。那是什么"公平"意思是:这意味着进入队列的第一个线程将是第一个获得锁定的线程。

  

如果锁不公平将会发生什么?

这意味着线程获取锁定的顺序不需要与它们进入队列的顺序相同。他们可能以该顺序获取锁定,或者他们可能不会。它是JVM实现者的选择。通常,JVM实现者会尝试做一些能够最大化某些"典型"应用

  

在t = 2 th1时同时释放锁定......

当你试图解释多线程程序的行为时,没有任何理由说两个事件同时发生。它只会使解释复杂化,并没有提供任何更深入的见解,而不是假装它不会发生。

  

...某些线程th3调用lock.tryLock()

reentrantLock.tryLock()方法很特别。如果锁是公平的,那么在某些情况下,调用tryLock()的线程显然可以在等待它的其他线程之前获取锁。我不完全理解可能发生的情况,但你可以在Javadoc中阅读它:https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/locks/ReentrantLock.html#tryLock()(搜索单词," barging"。)

如果当th1释放它时th2正在等待锁定,那么显然有一些时间窗口,在此期间th3可以"插入"与tryLock()并在获得机会之前获得它。我不知道如何定义那个时间窗口。

请注意,reentrantLock.tryLock(n) 不会具有相同的" barging"行为。