@TOC
前言
上篇文章讲解了AQS,今天就讲讲显示锁Lock
什么是Lock
Lock是一接口,实现了锁功能的接口,基于AQS来实现的。
lock的两大根接口,Lock和ReadWriteLock。
在Lock之前,java通过synchronized来实现锁功能的,在JDK15之后,并发包多了个Lock接口还有其实现来实现锁功能。
Lock的实现方式
因为Lock是一个接口,所以需要对应的实现,
java的并发提供了Lock的实现类ReentrantLock(可重入锁)。
ReadWriteLock(读写锁)的现类是ReentrantReadWriteLock。
Lock与synchronized的区别
1. synchronized是java中的一个关键字,也就是说是Java语言内置的特性
Lock是接口,它下面有很多的实现类。
- synchronize会自动释放锁
Lock需要‘手动’释放。 - synchronize不知道线程有没有获取到锁
lock可以知道是否获取到锁
4、synchronize是非公平锁
lock可以是公平锁,也可以是非公平锁。
5、synchronize等待不中断
lock等待可中断。
6、synchronize可以锁对象、类、代码块
而lock锁住的是代码块。
Lock代码实现
/**
* @version 1.0
* @Description LockDemo
* @Author wb.yang
*/
public class LockDemo {
/**
* 创建一个lock锁
*/
private static Lock lock = new ReentrantLock();
/**
* 计数值
*/
private static int count = 0;
public static class CountThread extends Thread {
@Override
public void run() {
// 获得锁
lock.lock();
try {
//业务操作
count++;
} finally {
//释放锁
lock.unlock();
}
}
}
public static void main(String[] args) {
for (int i = 0; i < 1000; i++) {
new CountThread().start();
}
SleepTools.second(2);
System.out.println(count);
}
}
在代码中我们也可以看出,我们先是创建了一个lock,然后还有一个count变量。
接下来定义了一个线程方法,在方法中使用lock()方法,来获取锁,当只有获得锁后才会继续往下执行,然后执行业务操作,最后在finally 中释放锁。
然后在main方法中创建了1000个线程执行对count++,如果线程是不安全的话,那么结果是不正确的
然后看下运行结果,从结果中可以看出,正好是1000,说明我们的加锁成功,保证了线程的安全