1. StampedLock
StampedLock用于解决写锁饥饿问题。读没有结束的时候,也可以加写锁。
特点:
-
- 所有获取锁的方法,都返回一个邮戳Stamp,Stamp为零表示获取失败;
-
- 所有释放锁的方法,都需要一个邮戳Stamp,这个Stamp必须和成功获取锁时得到的Stamp一致;
-
- StampedLock是不可重入的。多次获取锁会导致死锁。
-
- StampedLock三种访问模式:
(1)Reading(读悲观模式);(2)Writing(写模式);(3)Optimistic reading(乐观读模式):支持读写并发,乐观认为读取时没人修改,假如被修改再实现升级为悲观读模式。
- StampedLock三种访问模式:
package com.juc.demo.ThreadLocalDemo;
import ch.qos.logback.core.model.INamedModel;
import java.sql.Time;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.util.concurrent.locks.StampedLock;
public class demo06 {
StampedLock stampedLock = new StampedLock();
public int num = 0;
public void write(int i) {
long stamp = stampedLock.writeLock();
try {
System.out.println(i + " is writing");
TimeUnit.SECONDS.sleep(1);
num ++;
} catch (InterruptedException e) {
throw new RuntimeException(e);
} finally {
stampedLock.unlockWrite(stamp);
}
}
public void read(int i) {
long stamp = stampedLock.readLock();
try {
System.out.println(i + " is reading");
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
throw new RuntimeException(e);
} finally {
stampedLock.unlockRead(stamp);
}
}
public void optimicRead(int number) {
long stamp = stampedLock.tryOptimisticRead();
System.out.println("optimicRead " + number + " is " + num);
boolean validate = true;
try {
TimeUnit.SECONDS.sleep(2);
validate = stampedLock.validate(stamp);
if (!validate) {
stamp = stampedLock.readLock();
}
System.out.println("optimicRead " + number + " get " + num + " 已被修改升级为悲观锁");
} catch (InterruptedException e) {
throw new RuntimeException(e);
} finally {
if(!validate) {
stampedLock.unlockRead(stamp);
}
}
}
public static void main(String[] args) {
demo06 d = new demo06();
for(int i=0; i<10; i++) {
int t = i;
new Thread(()->{
d.write(t);
}).start();
}
for(int i=0; i<10; i++) {
int t = i;
new Thread(()->{
d.optimicRead(t);
}).start();
}
try {
TimeUnit.MICROSECONDS.sleep(100);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
for(int i=0; i<10; i++) {
int t = i;
new Thread(()->{
d.write(t);
}).start();
}
}
}
2. StampedLock缺点
-
- 不支持重入;
-
- 不支持条件变量(condition);
-
- 不要调用中断操作,interrupt()。