zoukankan      html  css  js  c++  java
  • 线程高级篇-读写锁ReentrantReadWriteLock

    转载原文:http://blog.csdn.net/john8169/article/details/53228016

    读写锁:  分为读锁和写锁,多个读锁不互斥,读锁和写锁互斥,这是有JVM自己控制的.如果代码只能读取数据,可以多人同时读,不能同时写,上读锁,

    如果代码要修改数据,只能有一个人写,而且不能同时读取.上写锁.

    线程进入写锁的前提条件:

      没有其他线程的读锁和写锁;

    线程进入读锁的前提条件:

      没有其他线程的写锁或写请求

        (a).重入方面其内部的WriteLock可以获取ReadLock,但是反过来ReadLock想要获得WriteLock则永远都不要想。 
         (b).WriteLock可以降级为ReadLock,顺序是:先获得WriteLock再获得ReadLock,然后释放WriteLock,这时候线程将保持Readlock的持有。反过来ReadLock想要升级为WriteLock则不可能,为什么?参看(a),呵呵. 
         (c).ReadLock可以被多个线程持有并且在作用时排斥任何的WriteLock,而WriteLock则是完全的互斥。这一特性最为重要,因为对于高读取频率而相对较低写入的数据结构,使用此类锁同步机制则可以提高并发量。 
         (d).不管是ReadLock还是WriteLock都支持Interrupt,语义与ReentrantLock一致。 
         (e).WriteLock支持Condition并且与ReentrantLock语义一致,而ReadLock则不能使用Condition,否则抛出UnsupportedOperationException异常。 

    package com.imooc.locks;
    
    import java.util.concurrent.locks.ReadWriteLock;
    import java.util.concurrent.locks.ReentrantReadWriteLock;
    
    public class Queue {
        
        private Object data = null;//共享数据,只能有一个线程写该数据,但可以多个线程读取该数据
        
        //读写锁
        ReadWriteLock rwl = new ReentrantReadWriteLock();
        
        // 相当于读操作  
        public void get() {  
            rwl.readLock().lock();  
            try {  
                System.out.println(Thread.currentThread().getName() + " be ready to read data!");  
                Thread.sleep((long) (Math.random() * 1000));  
                System.out.println(Thread.currentThread().getName() + "have read data :" + data);  
            } catch (InterruptedException e) {  
                e.printStackTrace();  
            } finally {  
                rwl.readLock().unlock();  
            }  
        }  
      
        // 相当于写操作  
        public void put(Object data) {  
            rwl.writeLock().lock();  
            try {  
                System.out.println(Thread.currentThread().getName() + " be ready to write data!");  
                Thread.sleep((long) (Math.random() * 1000));  
                this.data = data;  
                System.out.println(Thread.currentThread().getName() + " have write data: " + data);  
            } catch (InterruptedException e) {  
                e.printStackTrace();  
            } finally {  
                rwl.writeLock().unlock();  
            }  
        }  
    
    }
    package com.imooc.locks;
    
    import java.util.Random;
    
    public class ReadWriteLockTest {
        
        public static void main(String[] args) {
        
            final Queue q3 = new Queue();  
            
            for (int i = 0; i < 3; i++) {  
                new Thread() {  
                    public void run() {  
                        while (true) {  
                            q3.get();  
                        }  
                    }  
                }.start();  
                new Thread() {  
                    public void run() {  
                        while (true) {  
                            q3.put(new Random().nextInt(10000));  
                        }  
                    }  
                }.start();  
            }  
        }
    } 
    Thread-0 be ready to read data!
    Thread-2 be ready to read data!
    Thread-4 be ready to read data!
    Thread-0have read data :null
    Thread-2have read data :null
    Thread-4have read data :null
    Thread-1 be ready to write data!
    Thread-1 have write data: 3101
    Thread-1 be ready to write data!
    Thread-1 have write data: 8258
    Thread-1 be ready to write data!
    Thread-1 have write data: 7242
    Thread-3 be ready to write data!
    Thread-3 have write data: 4810
    Thread-5 be ready to write data!
    Thread-5 have write data: 7597
    Thread-5 be ready to write data!
    Thread-5 have write data: 8800
    Thread-0 be ready to read data!
    Thread-4 be ready to read data!
    Thread-2 be ready to read data!
    Thread-0have read data :8800
    Thread-2have read data :8800
    Thread-4have read data :8800
    Thread-1 be ready to write data!
    Thread-1 have write data: 6606
    Thread-1 be ready to write data!
    Thread-1 have write data: 5436
    Thread-1 be ready to write data!
    Thread-1 have write data: 3912
    Thread-1 be ready to write data!
    Thread-1 have write data: 7689
    Thread-3 be ready to write data!
    Thread-3 have write data: 3102
    Thread-3 be ready to write data!
    Thread-3 have write data: 466
    Thread-3 be ready to write data!
    Thread-3 have write data: 7377
    Thread-3 be ready to write data!
    Thread-3 have write data: 5461
    Thread-3 be ready to write data!
    Thread-3 have write data: 175
    Thread-3 be ready to write data!
    Thread-3 have write data: 8805
    Thread-3 be ready to write data!
    Thread-3 have write data: 8898
    Thread-5 be ready to write data!
    Thread-5 have write data: 8823
    Thread-5 be ready to write data!
    Thread-5 have write data: 5615
    Thread-5 be ready to write data!
    Thread-5 have write data: 8118
    Thread-0 be ready to read data!
    Thread-2 be ready to read data!
    Thread-4 be ready to read data!
    Thread-0have read data :8118
    Thread-2have read data :8118
    Thread-4have read data :8118
    Thread-1 be ready to write data!
    Thread-1 have write data: 5314
    Thread-1 be ready to write data!
    

      从打印结果可以看出:

    多个线程可以同时读取数据,但是只有一个线程可以写数据;

  • 相关阅读:
    Android 开发 深入理解Handler、Looper、Messagequeue 转载
    Android 开发 Handler的基本使用
    Java 学习 注解
    Android 开发 AlarmManager 定时器
    Android 开发 框架系列 百度语音合成
    Android 开发 框架系列 Google的ORM框架 Room
    Android 开发 VectorDrawable 矢量图 (三)矢量图动画
    Android 开发 VectorDrawable 矢量图 (二)了解矢量图属性与绘制
    Android 开发 VectorDrawable 矢量图 (一)了解Android矢量图与获取矢量图
    Android 开发 知晓各种id信息 获取线程ID、activityID、内核ID
  • 原文地址:https://www.cnblogs.com/Wanted-Tao/p/6379363.html
Copyright © 2011-2022 走看看