理解认识读写锁
- 所谓读写锁,即是读锁和写锁的统称,它是两种锁,但放在同一个对象里
- 它把对共享资源的访问者划分成读者和写者,读者只对共享资源进行读访问,写者则需要对共享资源进行写操作
- 在多处理器系统中,它允许同时有多个读者来访问共享资源,最大可能的读者数为实际的逻辑CPU数。写者是排他性的,一个读写锁同时只能有一个写者或多个读者(与CPU数相关),但不能同时既有读者又有写者
- 如果读写锁当前没有读者,也没有写者,那么写者可以立刻获得读写锁,否则它必须自旋在那里,直到没有任何写者或读者。
- 如果读写锁没有写者,那么多个读者都可以可以立即获得该读写锁,否则读者必须自旋在那里,直到写者释放该读写锁
- 总而言之
读锁是共享的
写锁是排他的
读-读能共存
读-写不能共存
写-写不能共存
实现
public class ReadWriteLock {
//创建读锁和写锁
private static final Object readWaitLock = new Object();
//读写线程的个数
private volatile int readCount = 0;
private volatile int writeCount = 0;
//操作的数据
public StringBuilder builder = new StringBuilder();
//读操作
public void read() throws InterruptedException {
//读可以有多个但是不能和写操作共存
//此处用while更好更安全 不然判断语句就只判断一次
while (writeCount != 0) {
//此时有写操作 所以进入等待
synchronized (readWaitLock) {
readWaitLock.wait();
}
}
//进行读操作 并将读操作计数器++
readCount++;
System.out.println("进程读操作:" + builder.toString());
//读操作执行完毕
readCount--;
synchronized (readWaitLock) {
readWaitLock.notify();
}
}
//写操作
public void write() throws InterruptedException {
//写操作只能有一个 而且不能和读共存
synchronized (readWaitLock) {
//这里还是使用while循环
while (writeCount != 0 && readCount != 0) {
//只要有读操作和写操作存在就等待
readWaitLock.wait();
}
//进行写操作 并将读操作计数器++
writeCount++;
System.out.println("写操作");
builder.append("aaa");
System.out.println("写执行完毕:" + builder.toString());
//写操作执行完毕
writeCount--;
}
synchronized (readWaitLock) {
readWaitLock.notify();
}
}
public static void main(String[] args) throws InterruptedException {
//创建多个读操作和写操作的线程
ReadWriteLock readWriteLock = new ReadWriteLock();
for (int i = 0; i < 10; i++) {
//十个读线程
Thread t = new Thread() {
@Override
public void run() {
try {
readWriteLock.read();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
//十个写线程
Thread t1 = new Thread() {
@Override
public void run() {
try {
readWriteLock.write();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
t1.start();
t.start();
}
//主线程休息会
Thread.sleep(2000);
}
}
- 上面代码是个人实现 如果有错误请批评指正
写操作
写执行完毕:aaa
写操作
写执行完毕:aaaaaa
进程读操作:aaaaaa
写操作
写执行完毕:aaaaaaaaa
进程读操作:aaaaaaaaa
进程读操作:aaaaaaaaa
写操作
写执行完毕:aaaaaaaaaaaa
进程读操作:aaaaaaaaaaaa
写操作
写执行完毕:aaaaaaaaaaaaaaa
写操作
写执行完毕:aaaaaaaaaaaaaaaaaa
写操作
写执行完毕:aaaaaaaaaaaaaaaaaaaaa
进程读操作:aaaaaaaaaaaaaaaaaaaaa
进程读操作:aaaaaaaaaaaaaaaaaaaaa
写操作
写执行完毕:aaaaaaaaaaaaaaaaaaaaaaaa
写操作
写执行完毕:aaaaaaaaaaaaaaaaaaaaaaaaaaa
进程读操作:aaaaaaaaaaaaaaaaaaaaaaaaaaa
进程读操作:aaaaaaaaaaaaaaaaaaaaaaaaaaa
写操作
写执行完毕:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
进程读操作:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
进程读操作:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
Process finished with exit code 0