Synchronized+CAS方式实现读写锁
思路
技术
- CAS 无锁机制,线程安全的更新读写状态
- synchronized 读线程的资源控制,控制写写的情况
代码
public class SynchronizerRW<T> {
private volatile int readState = 0;
private volatile int writeState = 0;
private T target;
private static final Unsafe unsafe;
private static final long readStateOffSet;
private static final long writeStateOffSet;
static {
try {
Field field = Unsafe.class.getDeclaredField("theUnsafe");
field.setAccessible(true);
unsafe = (Unsafe) field.get(null);
readStateOffSet = unsafe.objectFieldOffset
(SynchronizerRW.class.getDeclaredField("readState"));
writeStateOffSet = unsafe.objectFieldOffset
(SynchronizerRW.class.getDeclaredField("writeState"));
} catch (Exception e) {
throw new Error(e);
}
}
public SynchronizerRW(T target) {
if (null == target) throw new IllegalArgumentException("target must not be null !");
this.target = target;
}
private boolean compareAndSetReadState(int expect, int update) {
return unsafe.compareAndSwapInt(this, readStateOffSet, expect, update);
}
private boolean compareAndSetWriteState(int expect, int update) {
return unsafe.compareAndSwapInt(this, writeStateOffSet, expect, update);
}
public T readLock() {
for (; ; ) {
if (readState == 0 && compareAndSetWriteState(writeState, writeState + 1)) {
return target;
}
}
}
public void readUnLock() {
for (; ; ) {
if (compareAndSetWriteState(writeState, writeState - 1)) {
return;
}
}
}
public void writeLock(Write<T> write) {
for (; ; ) {
if (writeState == 0 && compareAndSetReadState(readState, readState + 1)) {
break;
}
}
synchronized (target) {
write.modify(target);
readState--;
}
}
public interface Write<T> {
void modify(T t);
}
}
测试
public class SynchronizedWRTest {
static class Student {
int count = 0;
public int getCount() {
return count;
}
public void setCount(int count) {
this.count = count;
}
@Override
public String toString() {
return count + "==" + Thread.currentThread().getName();
}
}
static class ReadThread extends Thread {
private SynchronizerRW<Student> studentSynchronizerRW;
public ReadThread(SynchronizerRW<Student> studentSynchronizerRW) {
this.studentSynchronizerRW = studentSynchronizerRW;
}
@Override
public void run() {
System.out.println("读线程程:" + studentSynchronizerRW.readLock());
studentSynchronizerRW.readUnLock();
}
}
static class WriteThread extends Thread {
private SynchronizerRW<Student> studentSynchronizerRW;
public WriteThread(SynchronizerRW<Student> studentSynchronizerRW) {
this.studentSynchronizerRW = studentSynchronizerRW;
}
@Override
public void run() {
studentSynchronizerRW.writeLock(student -> {
System.out.println("写线程写开始:" + student);
student.count++;
System.out.println("写线程写结束:" + student);
});
}
}
public static void main(String[] args) {
SynchronizerRW<Student> studentSynchronizerRW = new SynchronizerRW<>(new Student());
for (int i = 0; i < 10; i++) {
if (i % 2 == 0) {
Thread t = new ReadThread(studentSynchronizerRW);
t.start();
} else {
Thread t = new WriteThread(studentSynchronizerRW);
t.start();
}
}
}
}
结果
