版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u014745069/article/details/82718694
可替代synchronized的手动锁
ReentrantLock是Lock接口的一个实现,可以用于替代synchronized。
使用ReentrantLock可以完成类似synchronized(this)的功能,需要注意的是,就算线程已经执行完毕,Lock也不会自动释放锁,必须要手动释放锁!!!
与synchronized不同的是:使用synchronized锁定的话如果遇到异常,JVM会自动释放锁,但是Lock必须手动释放锁,因此经常在finally中进行锁的释放。
程序示例
public class ReentrantLockDemo {
Lock lock = new ReentrantLock();
void m1() {
try {
lock.lock();
for (int i = 0; i < 10; i++) {
TimeUnit.SECONDS.sleep(1);
System.out.print(i + " ");
}
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();// 比较一下未释放锁前后的执行区别
}
}
void m2() {
lock.lock();
System.out.println("m2...");
lock.unlock();
}
public static void main(String[] args) {
ReentrantLockDemo r1 = new ReentrantLockDemo();
new Thread(r1::m1).start();
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
new Thread(r1::m2).start();
}
}
执行结果:
tryLock尝试锁定
将m2()方法修改成如下形式,再次执行,观察结果:
/**
* 使用tryLock进行尝试锁定,不管锁定与否,方法都将继续执行, 可以根据tryLock的返回值来判断是否锁定,
* 也可以指定tryLock的时间,由于tryLock(time)抛出异常,所以注意unLock的处理,必须放在finally中。 <br>
* 作者: mht<br>
* 时间:2018年9月15日-下午10:07:42<br>
*/
void m2() {
// boolean locked = lock.tryLock();
// System.out.println("m2..." + locked);
// if (locked) lock.unlock();
boolean locked = false;
try {
locked = lock.tryLock(3, TimeUnit.SECONDS);
System.out.print("m2 resume... ");
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
if (locked)
lock.unlock();
}
}
执行结果(修改m2后继续执行第一段代码中的main方法):
Lock 的tryLock()方法支持有参和无参,根据实际需要可以指定具体的等待时间,或不进行等待(如注释掉的代码)。