内置锁 synchronized
Java提供一种内置锁机制来支持原子性:synchronized,他是一种隐性锁,他隐式的获取锁,却把锁的获取与释放固化了。
synchronized可以对方法和代码块进行同步
//对方法同步
public synchronized void method(){
..............................
}
//对代码块同步
public void method(){
synchronized(obj){
..........................
}
}
显式锁 Lock接口
而Java SE 5之后,并发包中新增了Lock接口(以及相关实现类)用来实现锁功能,它提供了与synchronized关键字类似的同步功能,只是在使用时需要显式地获取和释放锁。虽然它缺少了(通过synchronized块或者方法所提供的)隐式获取释放锁的便捷性,但是却拥有了锁获取与释放的可操作性、可中断的获取锁以及超时获取锁等多种synchronized关键字所不具备的同步特性。
Java 5 提供了Lock与ReadWriteLock两个接口,ReadWriteLock可以实现对共同资源的并发访问
为Lock接口提供了ReentrantLock(可重入锁)实现类;
为ReadWriteLock接口提供了ReentrantReadWriteLock实现类;
Lock接口提供的synchronized关键字所不具备的主要特性如表
Lock的API
可重入锁 ReentrantLock
使用ReentrantLock的代码格式
public class x{
//定义锁对象
private final Lock lock = new ReentrantLock();
public void method(){
//加锁
try{
//需要保证线程安全的代码
} finally{
lock.unlock(); //使用finally保证锁的释放
}
}
}
要将获取锁的过程写在try块中,因为如果在获取锁(自定义锁的实现)时发生了异常,异常抛出的同时,也会导致锁无故释放。
ReentrantLock具有可重入性,也就是说,一个线程可以对已被加锁的ReentrantLock锁再次加锁。ReentrantLock对象会维持一个计数器来追踪lock()方法的嵌套调用,线程每次调用lock()方法加锁后,必须显示的调用unlock()方法解锁。