读写锁ReentrantReadWriteLock:读读共享,读写互斥,写写互斥

深藏阁楼爱情的钟 2022-04-10 06:16 302阅读 0赞

JDK1.5之后,提供了读写锁ReentrantReadWriteLock,读写锁维护了一对锁,一个读锁,一个写锁,通过分离读锁和写锁,使得并发性相比一般的排他锁有了很大提升。在读多写少的情况下,读写锁能够提供比排他锁更好的并发性和吞吐量。

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0FwZW9wbA_size_16_color_FFFFFF_t_70

从源码中可以看出,读写锁中同样依赖队列同步器Sync(AQS)实现同步功能,而读写状态就是其同步器的同步状态。下面从例子中来说明:读读共享,读写互斥,写写互斥。

代码如下:

  1. public class ReentrantWriteReadLockTest {
  2. ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
  3. ReadLock readLock = lock.readLock();
  4. WriteLock writeLock = lock.writeLock();
  5. public void read(){
  6. try {
  7. readLock.lock();
  8. System.out.println("线程"+Thread.currentThread().getName()+"进入。。。");
  9. Thread.sleep(3000);
  10. System.out.println("线程"+Thread.currentThread().getName()+"退出。。。");
  11. } catch (InterruptedException e) {
  12. e.printStackTrace();
  13. }finally{
  14. readLock.unlock();
  15. }
  16. }
  17. public void write(){
  18. try {
  19. writeLock.lock();
  20. System.out.println("线程"+Thread.currentThread().getName()+"进入。。。");
  21. Thread.sleep(3000);
  22. System.out.println("线程"+Thread.currentThread().getName()+"退出。。。");
  23. } catch (InterruptedException e) {
  24. e.printStackTrace();
  25. }finally{
  26. writeLock.unlock();
  27. }
  28. }
  29. public static void main(String[] args) {
  30. final ReentrantWriteReadLockTest wr = new ReentrantWriteReadLockTest();
  31. Thread t1 = new Thread(new Runnable() {
  32. public void run() {
  33. wr.read();
  34. }
  35. }, "t1");
  36. Thread t2 = new Thread(new Runnable() {
  37. public void run() {
  38. wr.read();
  39. }
  40. }, "t2");
  41. Thread t3 = new Thread(new Runnable() {
  42. public void run() {
  43. wr.write();
  44. }
  45. }, "t3");
  46. Thread t4 = new Thread(new Runnable() {
  47. public void run() {
  48. wr.write();
  49. }
  50. }, "t4");
  51. t1.start();
  52. t2.start();
  53. //t3.start();
  54. //t4.start();
  55. }
  56. }

当我们启动线程t1和t2时,结果如下:

20181228095614196.jpg

线程t1和t2可以同时进入,说明了读读共享!

当我们启动线程t2和t3时,结果如下:

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0FwZW9wbA_size_16_color_FFFFFF_t_70 1

一个线程必须等待另一个线程退出,才能进入,说明了读写互斥!

当我们启动线程t3和t4时,结果如下:

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0FwZW9wbA_size_16_color_FFFFFF_t_70 2

一个线程必须等待另一个线程退出,才能进入,说明了写写互斥!

以上实例说明,读写锁ReentrantReadWriteLock:读读共享,读写互斥,写写互斥!

发表评论

表情:
评论列表 (有 0 条评论,302人围观)

还没有评论,来说两句吧...

相关阅读

    相关 互斥

    一、线程互斥方式。 --- 互斥锁 1、什么是互斥锁?特点怎么样? 互斥锁是专门用于处理线程之间互斥的一种方式,它有两种:上锁状态/解锁状态。 如果互斥锁处于上锁状

    相关 ReentrantReadWriteLock

    1. 写锁比读锁的优先级要高,拥有写锁之后还可以再获取读锁,但是拥有读锁的线程在释放前无法再获取写锁。 2. 允许锁降级,即从写锁降级为读锁,实现的步骤是:先获取写锁,再获