ReentrantReadWriteLock读写锁
在实际开发中我们对共享资源进行操作,读操作远远大于读操作,在没有写操作的时候,应该允许多个线程可以对他进行进行读取,而有线程进行写操作的时候,其他线程和写操作和读操作都应该阻塞,读写锁的特点就是读读并行,
读写和写写阻塞。
特点:
-
公平选择性:支持非公平(默认)和公平的锁获取方式,吞吐量还是非公平优于公平。
-
重进入:读锁和写锁都支持线程重进入。
-
锁降级:遵循获取写锁、获取读锁再释放写锁的次序,写锁能够降级成为读锁。
readLock()&readLock()
@Slf4j
public class Test2 {
public static void main(String[] args) {
ReentrantReadWriteLock readWriteLock = new ReentrantReadWriteLock();
ReentrantReadWriteLock.ReadLock readLock = readWriteLock.readLock();
ReentrantReadWriteLock.WriteLock writeLock = readWriteLock.writeLock();
new Thread(() -> {
try {
readLock.lock();
TimeUnit.SECONDS.sleep(1);
log.debug("1");
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
readLock.unlock();
}
}).start();
new Thread(() -> {
try {
readLock.lock();
TimeUnit.SECONDS.sleep(1);
log.debug("2");
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
readLock.unlock();
}
}).start();
new Thread(() -> {
try {
readLock.lock();
TimeUnit.SECONDS.sleep(1);
log.debug("3");
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
readLock.unlock();
}
}).start();
}
}
发现打印都是同一时刻发生的并没有发生阻塞的情况
readLock()&writeLock()
@Slf4j
public class Test2 {
public static void main(String[] args) {
ReentrantReadWriteLock readWriteLock = new ReentrantReadWriteLock();
ReentrantReadWriteLock.ReadLock readLock = readWriteLock.readLock();
ReentrantReadWriteLock.WriteLock writeLock = readWriteLock.writeLock();
new Thread(() -> {
try {
writeLock.lock();
TimeUnit.SECONDS.sleep(1);
log.debug("写1");
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
writeLock.unlock();
}
}).start();
new Thread(() -> {
try {
readLock.lock();
TimeUnit.SECONDS.sleep(1);
log.debug("读1");
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
readLock.unlock();
}
}).start();
new Thread(() -> {
try {
readLock.lock();
TimeUnit.SECONDS.sleep(1);
log.debug("读2");
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
readLock.unlock();
}
}).start();
}
}
发现读还是一起执行,但是都是等待写释放释放后才开始执行说明读写是互斥的
writeLock()&writeLock()
@Slf4j
public class Test2 {
public static void main(String[] args) {
ReentrantReadWriteLock readWriteLock = new ReentrantReadWriteLock();
ReentrantReadWriteLock.ReadLock readLock = readWriteLock.readLock();
ReentrantReadWriteLock.WriteLock writeLock = readWriteLock.writeLock();
new Thread(() -> {
try {
writeLock.lock();
TimeUnit.SECONDS.sleep(1);
log.debug("写1");
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
writeLock.unlock();
}
}).start();
new Thread(() -> {
try {
writeLock.lock();
TimeUnit.SECONDS.sleep(1);
log.debug("写2");
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
writeLock.unlock();
}
}).start();
}
}
发现写写也是互斥的