锁和条件的关键
-
锁用来保护代码片段,任何时刻只能有一个线程执行被保护的代码。
-
锁可以管理试图进入被保护代码段的线程。
-
锁可以拥有一个或多个相关的条件对象。
-
每个条件对象管理那些已经进入被保护代码段但还不能运行的线程。
synchronized的理解
synchronized是隐式锁,比起ReentrantLock更简单,能达到的功能也没那么完善。但是,在大多数情况下,不需要高度的锁定控制,synchronized给我们提供了一种嵌入到Java语言内部的机制。
从1.0版开始,Java的每一个对象都有一个内部锁。如果一个方法用synchronized声明,那么对象的锁将保护整个方法。也就是说,要调用该方法,线程必须获得内部的对象锁。功能表现上与用Lock显示加锁是一致的,但只需要对方法加该关键字即可实现:
public synchronized void method() {
// do something...
}
这个内部对象锁不要与ReetrantLock弄混,ReetrantLock可以支持多个条件,该内部对象锁只支持一个条件,使用wait和notifyAll/notify。功能与Condition的方法类似。
将静态方法声明为synchronized也是合法的。因为类也是一个对象,每一个对象里都有内部锁。
内部锁的限制
-
不能中断一个正在试图获得锁的线程。
-
试图获得锁时不能设定超时。
-
每个锁仅有单一的条件,可能时不够的。
使用建议:
-
不要使用。因为在很多情况下可以使用java.util.concurrent包中的一种机制,它会为我们处理所有的加锁。
-
如果synchronized关键字真的很适合,那就用。代码行数越少,bug越少。
-
除非万不得已,才使用Lock/Conditioin。