tryLock方法 - 非阻塞方法?

时间:2014-12-22 12:38:36

标签: java concurrency

tryLock方法的文档说它是一种非阻塞方法 允许您获取/获取锁定(如果在调用方法时可以获得)。

但是我想知道:你怎么能获得锁定并且仍然保证同时保证 你的方法(tryLock)是非阻塞的?!获取锁定意味着您已经完成了 试图访问受保护的代码部分,以便它应该阻止(如果你不幸运的话) 即你应该至少在某些情况下阻止)。任何人都可以解释逻辑 这背后?纯粹从逻辑的角度来看:我不太明白这是怎么回事 完成(保证方法不会阻止)。除非他们使用另一个 线程当然在tryLock本身的代码中......

http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/locks/Lock.html#tryLock%28%29

2 个答案:

答案 0 :(得分:4)

这些机制的大多数实现都使用所谓的CAS CPU指令来基于变量执行原子操作。 CAS表示比较和交换。它们会查看变量的值,如果它是您所期望的,则可以更改它。这提供了线程安全(非阻塞/锁定)方式来对多线程数据进行比较。

CAS指令以原子方式执行以下操作:

private int stored = 0;
public int compareAndSwap(int expectedValue , int newValue)

   if(expectedValue == stored)
       stored = newValue;

   return stored;
}

这些非阻塞机制通常只是重试上述函数,直到成功(返回值为预期值)。由于重试循环非常短,每次迭代中线程中断的可能性很小(或者实际上OS调度程序甚至会使其无法实现)。

实际的java锁定(Lock只是它们实现的接口)更加复杂,因为它们提供了额外的功能。但实质上,CAS机制是大多数非阻塞线程安全类的基础。

如果您对锁定的内部工作感兴趣,Java Concurrency in Practice是一个很好的来源。轻松地开始Java并发可以做什么,并推进它如何做到这一点。 (即使对于非Java程序员来说,它也是一个很好的来源)。你的问题在第15章处理。

答案 1 :(得分:1)

  

获取锁定意味着您正在尝试访问受保护的代码部分,因此它应该阻止(如果您不幸运,即至少应该在某些情况下阻止)

如果这是您想要的行为,您应该只使用lock方法。 tryLock的重点是当想要在锁定不可用时阻止时使用它。

如何实现而言,取决于个别实现 - 所以你应该看看你感兴趣的实现。我个人认为使用{{1}的人是合理的。在内部,如果他们知道在synchronized块内没有运行任何用户指定的代码 - 换句话说,它可以暂时阻止内部管家,但不会在锁本身的持续时间内阻塞。

当然,有权访问适当的机器级指令的实现可以使用比较和交换等...哎呀,AtomicBoolean.compareAndSet可能用于非常简单的版本。