tryLock
方法的文档说它是一种非阻塞方法
允许您获取/获取锁定(如果在调用方法时可以获得)。
但是我想知道:你怎么能获得锁定并且仍然保证同时保证
你的方法(tryLock
)是非阻塞的?!获取锁定意味着您已经完成了
试图访问受保护的代码部分,以便它应该阻止(如果你不幸运的话)
即你应该至少在某些情况下阻止)。任何人都可以解释逻辑
这背后?纯粹从逻辑的角度来看:我不太明白这是怎么回事
完成(保证方法不会阻止)。除非他们使用另一个
线程当然在tryLock本身的代码中......
http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/locks/Lock.html#tryLock%28%29
答案 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
可能用于非常简单的版本。