隐式(Synchronized)锁和显式(java.util.Lock)锁
为了控制多个线程按照正确的顺序来访问共享数据,Java提供了提供了两种锁方案
1.隐式锁(Synchronized)
这一种就是比较大家熟悉的synchronized关键字,因为Java中每个对象都实现了lock的功能,所以synchronized正是利用了这一特性,来控制并发访问.使用synchronized关键字可以保证使用同一个锁的方法或代码块在不同的线程里执行时是原子的即不可分割的(Atomic),这是通过阻塞(blocking)的方式来实现原子性,后面的文章会提到非阻塞(non-blocking)的方式实现原子操作.
public synchronized void safeMethod() {
} //Lock是该方法所属的对象
public static void safeMethod(){
} //Lock是该类的class对象
synchronized(xxxObject){
} //Lock是xxxObject
这种方法因为不能显式的对Lock对象进行各种操作,所以有很多不便性,JDK1.5引入了显式锁
2.显式锁
可以查看 java.util.,concurrent.Lock 接口,实现该接口的类提供了显式锁的功能,我们看看Lock接口
void lock(); //尝试获取锁,若得不到着等待(不可中断,类似于synchronized方式)
void lockInterruptibly() ; //可中断的尝试获取锁
boolean tryLock();尝试获取锁,不管得到与否立即返回
boolean tryLock(long time, TimeUnit unit)尝试获取锁,若得不到等到一段时间
void unlock();// 释放锁
Condition newCondition();//创建于该锁相关的条件变量,实现精确等待/唤醒
3.两者区别与联系
显式和隐式锁都能实现对共享资源的控制,两者在内存同步上是同样的机制,但是显式锁提供了更灵活更强大的接口
1.synchronized 对多个锁只能按照获得锁的顺序的反序释放(先获得后释放),显式锁可以
按照需要释放锁,无此约束.
2.显式锁提供可中断的获取锁的方法,lockInterruptibly
3.显式提供尝试获得锁方法
4.提供精度更细的等待与唤醒(利用Condition)
特别注意显式锁的 xx.lock()方法只是获取了xx对象表达的锁,并不是获取了xx内置的隐式锁,这个要注意区分,与synchronized(xx)是两回事