java 读写锁的使用及它的优点

网友投稿 414 2022-07-31


目录1.读写锁使用1.1 读读不互斥1.2 读写互斥1.3 写写互斥2.优点分析3.适用场景总结

前言:

读写锁(Readers-Writer Lock)顾名思义是一把锁分为两部分:读锁和写锁,其中读锁允许多个线程同时获得,因为读操作本身是线程安全的,而写锁则是互斥锁,不允许多个线程同时获得写锁,并且写操作和读操作也是互斥的。总结来说,读写锁的特点是:读读不互斥、读写互斥、写写互斥。

1.读写锁使用

在 java 语言中,读写锁是使用 ReentrantReadWriteLock 类来实现的,其中:

ReentrantReadWriteLock.ReadLock表示读锁,它提供了 lock 方法进行加锁、unlock 方法进行解锁。ReentrantReadWriteLock.WriteLock表示写锁,它提供了 lock 方法进行加锁、unlock 方法进行解锁。

它的基础使用如下代码所示:

// 创建读写锁

final ReentrantReadWriteLock readWriteLock = new ReentrantReadWriteLock();

// 获得读锁

final ReentrantReadWriteLock.ReadLock readLock = readWriteLock.readLock();

// 获得写锁

final ReentrantReadWriteLock.WriteLock writeLock = readWriteLock.writeLock();

// 读锁使用

readLock.lock();

try {

// 业务代码...

} finally {

readLock.unlock();

}

// 写锁使用

writeLock.lock();

try {

// 业务代码...

} finally {

writeLock.unlock();

}

1.1 读读不互斥

多个线程可以同时获取到读锁,称之为读读不互斥,如下代码所示:

// 创建读写锁

final ReentrantReadWriteLock readASvNCvDQHfWriteLock = new ReentrantReadWriteLock();

// 创建读锁

final ReentrantReadWriteLock.ReadLock readLock = readWriteLock.readLock();

Thread t1 = new Thread(() -> {

readLock.lock();

try {

System.out.println("[t1]得到读锁.");

Thread.sleep(3000);

} catch (InterruptedException e) {

e.printStackTrace();

} finally {

System.out.println("[t1]释放读锁.");

readLock.unlock();

}

});

t1.start();

Thread t2 = new Thread(() -> {

readLock.lock();

try {

System.out.println("[t2]得到读锁.");

Thread.sleep(3000);

} catch (InterruptedException e) {

e.printStackTrace();

} finally {

System.out.println("[t2]释放读锁.");

readLock.unlock();

}

});

t2.start();

以上程序执行结果如下:

1.2 读写互斥

读锁和写锁同时使用是互斥的(也就是不能同时获得),这称之为读写互斥,如下代码所示:

// 创建读写锁

final ReentrantReadWriteLock readWriteLock = new ReentrantReadWriteLock();

// 创建读锁

final ReentrantReadWriteLock.ReadLock readLock = readWriteLock.readLock();

// 创建写锁

final ReentrantReadWriteLock.WriteLock writeLock = readWriteLock.writeLock();

// 使用读锁

Thread t1 = new Thread(() -> {

readLock.lock();

try {

System.out.println("[t1]得到读锁.");

Thread.sleep(3000);

} catch (InterruptedException e) {

e.printStackTrace();

} finally {

System.out.println("[t1]释放读锁."http://);

readLock.unlock();

}

});

t1.start();

// 使用写锁

Thread t2 = new Thread(() -> {

writeLock.lock();

try {

System.out.println("[t2]得到写锁.");

Thread.sleep(3000);

} catch (InterruptedException e) {

e.printStackTrace();

} finally {

System.out.println("[t2]释放写锁.");

writeLock.unlock();

}

});

t2.start();

以上程序执行结果如下:

1.3 写写互斥

多个线程同时使用写锁也是互斥的,这称之为写写互斥,如下代码所示:

// 创建读写锁

final ReentrantReadWriteLock readWriteLock = new ReentrantReadWriteLock();

// 创建写锁

final ReentrantReadWriteLock.WriteLock writeLock = readWriteLock.writeLock();

Thread t1 = new Thread(() -> {

writeLock.lock();

try {

System.out.println("[t1]得到写锁.");

Thread.sleep(3000);

} catch (InterruptedException e) {

e.printStackTrace();

} finally {

System.out.println("[t1]释放写锁.");

writeLock.unlock();

}

});

t1.start();

Thread t2 = new Thread(() -> {

writeLock.lock();

try {

System.out.println("[t2]得到写锁.");

Thread.sleep(3000);

} catch (InterruptedException e) {

e.printStackTrace();

} finally {

System.out.println("[t2]释放写锁.");

writeLock.unlock();

}

});

t2.start();

以上程序执行结果如下:

2.优点分析

提高了程序执行性能:多个读锁可以同时执行,相比于普通锁在任何情况下都要排队执行来说,读写锁提高了程序的执行性能。避免读到临时数据:读锁和写锁是互斥排队执行的,这样可以保证了读取操作不会读到写了一半的临时数据。

3.适用场景

读写锁适合多读少写的业务场景,此时读写锁的优势最大。

总结

读写锁是一把锁分为两部分:读锁和写锁,其中读锁允许多个线程同时获得,而写锁则是互斥锁。它的完整规则是:读读不互斥、读写互斥、写写互斥。它适用于多读的业务场景,使用它可以有效的提高程序的执行性能,也能避免读取到操作了一半的临时数据。


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:java实现简单中国象棋(用java编写中国象棋棋盘)
下一篇:Java零基础也看得懂的单例模式与final及抽象类和接口详解(java抽象类可以用final)
相关文章

 发表评论

暂时没有评论,来抢沙发吧~