并发编程系列之ReentrantLock用法简介
ReentrantLock是实现底层的Lock接口的可重入锁实现。支持公平锁模式和非公平锁模式。
典型例子:
ReentrantLocl rlock = new ReentrantLock();
try {
rlock.lock();
// 业务处理
} finally {
rlock.unlock();
}
ReentrantLock是可重入锁,所以允许一个线程多次获取资源锁。第一次调用lock时,计数设置为1,再次获取资源锁时加1,调用unlock解锁,计数减1,直到减为0,释放锁资源,如图所示:
// 设置ReentrantLock为公平锁
ReentrantLock lock = new ReentrantLock(true);
在idea编辑器里查看ReentrantLock的方法:
挑一些常用方法进行描述
lock()
:如果共享资源最初是空闲的,调用lock会进行计数加1,并将锁提供给线程。会进行累加unlock()
:调用unlock方法,会进行计数减1,减为0时,释放资源锁tryLock()
:为了避免锁竞争,可以使用tryLock
,如果资源没有被其他线程持有,会返回true,加锁成功,已经被其他线程持有了,返回false,加锁失败tryLock(long timeout, TimeUnit unit)
:这个尝试加锁方法,多了一个超时时间lockInterruptably()
:如果资源空闲,则此方法获取锁,允许该线程在获取资源时被其他线程中断。如果该线程在获取锁过程,其它线程抢进来,获取锁过程会被中断并立即返回而不获取锁getHoldCount()
:此方法返回资源上持有的锁数的计数。isHeldByCurrentThread()
:如果当前线程持有资源锁,则此方法返回true例子:进行大数据的count统计,开启20个线程,如何保证线程安全,计数的正确性?
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.locks.ReentrantLock;
public class ReentrantLockCountExample {
private static volatile int count = 0;
static ReentrantLock lock = new ReentrantLock();
public static void countHandler() {
lock.lock();
try {
count++;
}finally {
lock.unlock();
}
}
public static void doCountConcurrent() throws InterruptedException {
int threads = 20;
CountDownLatch cdl = new CountDownLatch(threads);
for (int i = 0; i < threads; i++) {
new Thread(() -> {
for (int n = 0; n < 10000; n++) {
countHandler();
}
cdl.countDown();
}).start();
}
try {
cdl.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static void main(String[] args) throws InterruptedException {
long start = System.currentTimeMillis();
doCountConcurrent();
System.out.println("统计耗时:" + (System.currentTimeMillis() - start) + "ms");
System.out.println("result:"+ ReentrantLockCountExample.count);
}
}
版权说明 : 本文为转载文章, 版权归原作者所有 版权申明
原文链接 : https://smilenicky.blog.csdn.net/article/details/121654063
内容来源于网络,如有侵权,请联系作者删除!