结论
ReentrantLock 保证统一时刻,锁内只能有一个线程
ReentrantReadWriteLock 写锁时 锁内只能有一个线程
ReentrantReadWriteLock 读锁时 锁内能有多个线程
在多线程情况下
1. 如果业务上读的场景很多,ReentrantReadWriteLock 效率高于 ReentrantLock
2. 如果业务上读的写景很多,ReentrantReadWriteLock 效率等同于 ReentrantLock
案例
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.locks.ReentrantLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
public class DataRepository {
private static final List<Object> dataList = new ArrayList<>();
static {
dataList.add("1");
}
private final ReentrantReadWriteLock readWriteLock = new ReentrantReadWriteLock();
private final java.util.concurrent.locks.Lock readLock = readWriteLock.readLock();
private final java.util.concurrent.locks.Lock writeLock = readWriteLock.writeLock();
public Object getDataReadWriteLock(int index) {
readLock.lock();
try {
// 模拟耗时操作
Thread.sleep(1000);
System.out.println(System.currentTimeMillis() + " - getData - " + Thread.currentThread().getName());
return dataList.get(index);
} catch (Exception e) {
e.printStackTrace();
} finally {
readLock.unlock();
}
return null;
}
public void updateDataReadWriteLock(int index, Object newData) {
writeLock.lock();
try {
// 模拟耗时操作
Thread.sleep(1000);
System.out.println(System.currentTimeMillis() + " - updateData - " + Thread.currentThread().getName());
dataList.set(index, newData);
} catch (Exception e) {
e.printStackTrace();
} finally {
writeLock.unlock();
}
}
private final ReentrantLock lock = new ReentrantLock();
public Object getDataLock(int index) {
lock.lock();
try {
// 模拟耗时操作
Thread.sleep(1000);
System.out.println(System.currentTimeMillis() + " - getData - " + Thread.currentThread().getName());
return dataList.get(index);
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
return null;
}
public void updateDataLock(int index, Object newData) {
lock.lock();
try {
// 模拟耗时操作
Thread.sleep(1000);
System.out.println(System.currentTimeMillis() + " - updateData - " + Thread.currentThread().getName());
dataList.set(index, newData);
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
class Run5 {
public static void main(String[] args) throws InterruptedException {
DataRepository dataRepository = new DataRepository();
CountDownLatch latch = new CountDownLatch(3);
long startTime = System.currentTimeMillis();
for (int i = 0; i < 3; i++) {
Thread t1 = new Thread(() -> {
dataRepository.getDataReadWriteLock(0);
dataRepository.updateDataReadWriteLock(0, 2);
latch.countDown(); // 完成当前线程的工作
});
t1.start();
}
// 等待所有线程完成
latch.await();
long endTime = System.currentTimeMillis();
System.out.println("所有线程完成的总耗时为:" + (endTime - startTime) + "毫秒");
CountDownLatch latchLock = new CountDownLatch(3);
long startTimeLock = System.currentTimeMillis();
for (int i = 0; i < 3; i++) {
Thread t1 = new Thread(() -> {
dataRepository.getDataLock(0);
dataRepository.updateDataLock(0, 2);
latchLock.countDown(); // 完成当前线程的工作
});
t1.start();
}
// 等待所有线程完成
latchLock.await();
long endTimeLock = System.currentTimeMillis();
System.out.println("所有线程完成的总耗时为:" + (endTimeLock - startTimeLock) + "毫秒");
}
结果