1. ReentrantLock VS Synchronized
- ReentrantLock 提供了较多的API,可以灵活的在线程中获取到锁的一些数据;而Synchronized则无法获得锁的数据。
- ReentrantLock 可以更加细粒度的控制线程代码块。
- ReentrantLock 相对于Synchronized性能更高效一些。
2. ReentrantReadWriteLock
- 对于多个线程的读,不会加锁;提高了吞吐量。而使用其他的锁,为了保证线程的安全性,不管是读还是写,都会加锁;造成性能的一些影响。 写锁在时候的时候,读锁会处于一直waiting的状态。
3. StampedLock
- StampedLock悲观锁使用StampedLock做读写锁。 一个StampedLock可以直接获取到ReadLock和WriteLock。这样的写法会和ReentrantReadWriteLock一样,写锁在使用的时候,导致读锁的waiting。
public class StampedLockDemo1 {
private static final StampedLock lock = new StampedLock();
private static final List<Long> DATA = new ArrayList<>();
public static void main(String[] args) {
new Thread(() -> {
for (;;) {
write();
}
}).start();
IntStream.rangeClosed(1, 10).forEach(item -> {
new Thread(() -> {
for (;;) {
read();
}
}).start();
});
}
private static void read() {
long stamped = -1;
try {
stamped = lock.readLock();
String readData = DATA.stream()
.map(String::valueOf)
.collect(Collectors.joining(", ", "R-->", ""));
Optional.of(readData).ifPresent(System.out::println);
sleep(2);
} finally {
lock.unlockRead(stamped);
}
}
private static void write() {
long stamped = -1;
try {
stamped = lock.writeLock();
long timeMillis = System.currentTimeMillis();
System.out.println("C-> " + timeMillis);
DATA.add(timeMillis);
sleep(2);
} finally {
lock.unlockWrite(stamped);
}
}
private static void sleep(long sec) {
try {
TimeUnit.SECONDS.sleep(sec);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
- StampedLock 乐观读<适合读多写少>
private static void read() {
long stamped = lock.tryOptimisticRead();
if (lock.validate(stamped)) {
try {
stamped = lock.readLock();
String readData = DATA.stream()
.map(String::valueOf)
.collect(Collectors.joining(", ", "R-->", ""));
Optional.of(readData).ifPresent(System.out::println);
sleep(1);
}finally {
lock.unlockRead(stamped);
}
}
}