1、ReentrantLock介绍
2、ReentrantLock的方法
3、ReentrantLock的使用
好了,开始正文
1、ReentrantLock介绍
1) 在Java5.0以前,协调对共享对象的访问可以使用的机制只有synchronized和volatile,也称内置锁。
在Java5.0之后呢,出现了一种新的机制:ReentrantLock,也称外置锁。
这个机制的出现并不是想要替代内置锁,而是在内置加锁机制不适用时,作为一种可选择的高级功能。
怎么就高级了呢?
ReentrantLock,它实现了一个Lock接口,这个Lock接口中定义了一组抽象的加锁操作。
而Lock提供了一种无条件的、可轮询的、定时的以及可中断的锁获取操作,这就是它优于synchronized的地方。
2)synchronized是一个关键字,修饰方法和代码块的时候,它范围就在那对花括号里,其它的事情也不需要操心,即是Java内置的锁;
ReentrantLock是一个类,加锁方式的实现,是要手动加锁跟手动释放锁,故被称为外置锁。
2、ReentrantLock的方法
ReentrantLock实现了Lock接口,
那这个无条件的、可轮询的、定时的以及可中断的锁获取操作由Lock接口的方法可体现
1)void lock();//Acquires the lock
(源码释义),获取锁
2)void lockInterruptibly() throws InterruptedException;
//Acquires the lock unless the current thread is {@linkplain Thread#interrupt interrupted}.
得到这个锁,除非当前线程被打断了。
这一点就是可中断的锁操作,当前的线程若是被打断了,就立即返回;synchronized是没有这种操作的。
3)boolean tryLock();
//Acquires the lock only if it is free at the time of invocation
尝试获取锁,且获取到就返回true,否则返回false。
4)boolean tryLock(long time, TimeUnit unit) throws InterruptedException;
//Acquires the lock if it is free within the given waiting time and the current thread has not been {@linkplain Thread#interrupt interrupted}.
如果在给定的时间锁是空闲的并且没有被打断,就去获取锁。
这个方法中两个参数:long time->给定一个时间,它的单位由后面的TimeUnit unit决定。
补充一下,这个TimeUnit
是一个枚举类,最常使用的地方是是代替了Thread.sleep(毫秒)
方法,替换成了TimeUnit.时间单位.sleep(数值),比如,TimeUnit.SECONDS.sleep(2)
,睡上它两秒。
3)、4)两点就是可轮询的、定时的所获取操作。
相比较而言,synchronized就不能人为的设置这些东西。
5)void unlock();//Releases the lock
,释放锁,这一步是要手动添加在代码中的,不添加就会出大问题。
以上,1)、2)、3)、4)就是进行加锁;5)当然是释放锁
3、ReentrantLock的使用
首先看一下synchronized
的使用;
1)同步代码块
synchronized public static void fun1() {
//do something
}
2)同步方法
public static void fun2() {
synchronized (Object.class) {
//do something
}
}
再比较ReentrantLock
public static void fun3() {
Lock lock = new ReentrantLock();//获取ReentrantLock对象
try {
lock.lock();
//or lock.lockInterruptibly();
//or lock.tryLock();
//or lock.tryLock(long time, TimeUnit unit);
//->lock.tryLock(2, TimeUnit.SECONDS);//睡2秒获取不到锁就放弃
//do something
} finally {
lock.unlock();
}
}