读写锁其实就是共享锁+排他锁
场景:在高并发的情况下,如果存在一部分数据很少被修改却大量被读取的情况下,可以使用读写锁的方式,这种锁如字面意思,即:如果读取数据的线程获取锁时,则无法进行写入,如果有其他读取数据的线程也进来时,可以同时读取。如果写数据的线程获取锁时,则无法读取。
下面是示例:
public class Demo10 {
static ReentrantReadWriteLock reentrantReadWriteLock = new ReentrantReadWriteLock();
static ReentrantReadWriteLock.ReadLock readLock = reentrantReadWriteLock.readLock();
static ReentrantReadWriteLock.WriteLock writeLock = reentrantReadWriteLock.writeLock();
static Lock lock = new ReentrantLock();
static class Cat {
private String name;
private String weight;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getWeight() {
return weight;
}
public void setWeight(String weight) {
this.weight = weight;
}
@Override
public String toString() {
return "Cat{" +
"name='" + name + '\'' +
", weight='" + weight + '\'' +
'}';
}
}
static Cat cat = new Cat();
private static Cat red(Lock lock, CountDownLatch countDownLatch) {
try {
lock.lock();
Thread.sleep(1000);
System.out.println("red over!");
countDownLatch.countDown();
} catch (InterruptedException interruptedException){
interruptedException.printStackTrace();
} finally {
lock.unlock();
}
return Demo10.cat;
}
private static Cat write(Lock lock, CountDownLatch countDownLatch) {
try {
lock.lock();
Thread.sleep(1000);
System.out.println("write over!");
countDownLatch.countDown();
} catch (InterruptedException interruptedException){
interruptedException.printStackTrace();
} finally {
lock.unlock();
}
return Demo10.cat;
}
public static void main(String[] args) {
long start = System.currentTimeMillis();
final CountDownLatch countDownLatch = new CountDownLatch(20);
// Runnable red = () -> red(lock, countDownLatch);
// Runnable write = () -> write(lock, countDownLatch);
Runnable red = () -> red(readLock, countDownLatch);
Runnable write = () -> write(writeLock, countDownLatch);
for (int i = 0; i < 18 ; i++) {
new Thread(red).start();
}
for (int i = 0; i < 2; i++) {
new Thread(write).start();
}
try {
countDownLatch.await();
System.out.println(“结束时间一共花了多少秒呢?==>”+(System.currentTimeMillis() - start)/1000);
} catch (InterruptedException interruptedException) {
interruptedException.printStackTrace();
}
}
}