叙述
提到锁,就会想到数据库锁、Java内置锁、分布式锁
使用场景
首先,需要加锁的资源一定是临界资源,所谓临界资源就是在多线程的情况下,各个线程会进行抢占的资源。下面以一段代码来说明:
public class LockDemo {
private static int count = 500;
public static void main(String[] args) throws Exception {
ExecutorService threadPool = Executors.newFixedThreadPool(10);
for (int i = 0; i < 500; i++){
threadPool.submit(() -> {
count--;
});
}
threadPool.shutdown();
Thread.sleep(5000);
System.out.println(count);
}
}
结果:2
然后创建了500个任务,把这五百个任务丢到线程池里去处理,每个任务会对count进行减一。
理想情况下,count应该为0,但实际count最后为2。
其原因就是因为在多线程环境下,各个线程对count发生了资源的争夺,导致了数据的不安全性。
其中,count就是临界资源,多线程就是我们常说的并发环境。
加完Lock锁后的代码
public class LockDemo {
private static int count = 500;
public static void main(String[] args) throws Exception {
Lock lock = new ReentrantLock();
ExecutorService threadPool = Executors.newFixedThreadPool(10);
for (int i = 0; i < 500; i++){
threadPool.submit(() -> {
lock.lock();
count--;
lock.unlock();
});
}
threadPool.shutdown();
Thread.sleep(5000);
System.out.println(count);
}
}
代码整体没有太大变化,只是在count–前后做了加锁和减锁操作,最后无论代码运行多少次,结果都是0(需要注意的是这里忽略了可见性),没有出现未加锁时的少减情况。
这就是锁的使用场景,无论是数据库锁、java内置锁还是分布式锁,他们的使用场景都大同小异。
使用锁的目的就是为了控制临界资源的安全性。
如果使用了tryLock(),他会在判断在使用锁的情况下,默认跳过count–操作,最终结果是51。
如果不使用tryLock(),默认是等待解锁后继续往下执行。
Lock详解
使用如下代码创建Lock锁,Lock
是一个接口,而是实现ReentrantLock
类
// 默认非公平锁
Lock lock = new ReentrantLock();
// 公平锁
Lock lock = new ReentrantLock(true);
源码如下:
public ReentrantLock() {
sync = new NonfairSync();
}
public ReentrantLock(boolean fair) {
sync = fair ? new FairSync() : new NonfairSync();
}
Lock属性
void | lock()获得锁 |
---|---|
void | lockInterruptibly()获取锁定,除非当前线程是 interrupted 。 |
Condition | newCondition()返回一个新Condition绑定到该实例Lock实例。 |
boolean | tryLock()只有在调用时才可以获得锁。 |
boolean | tryLock(long time, TimeUnit unit)如果在给定的等待时间内是空闲的,并且当前的线程尚未得到 interrupted则获取该锁。 |
void | unlock();释放锁 |
文章参考:
https://blog.csdn.net/m0_50370837/article/details/124471888
https://blog.csdn.net/qq_42871327/article/details/115970315
https://mp.weixin.qq.com/s?__biz=MzU1MjMzNzUwNg==&mid=2247484229&idx=1&sn=9a67add64bf3c9fee15faf63c6df5c38&chksm=fb82ea48ccf5635ea0edc5ff40662680102d6e9e04ce30686332abd860e940f250b7cae0161c&scene=27