多线程学习之七读写锁

Read-Write Lock Pattern【读写】
一:Read-Write Lock Pattern的参与者
--->读写锁
--->数据(共享资源)
--->读线程
--->写线程


       

二Read-Write Lock Pattern模式什么时候使用
--->
 * 为了多线线程环境下保护数据安全,我们必须避免的冲突
 * 一个线程读取,另一个线程写入的read-write conflick
 * 一个线程写入,另一个线程写入的write-write conflick
 * 一个线程读取,另一个线程也在读取不会产生冲突
 *
 * 当线程想要获取读取锁定时:
 * -->已经有线程在执行写入,则等待。不等待,则发生read-write conflick
 * -->已经有线程在读取,则不需要等待。不存在read-read conflick
 *
 * 当线程想要获取写入锁定时:
 * -->已经有线程在执行写入,则等待。不等待,则发生write-write conflick
 * -->已经有线程在执行读取,则等待。不等待,则发生read-write conflick


--->利用同时(读取)不会引起数据冲突的特性,提高系统的性能
--->适合读取操作繁重时
--->适合读取操作比写入操作繁重时


三:Read-Write Lock Pattern思考
--->
四进阶说明
--->

 

读写锁

/**
 * 
 */
package com.benxq.thread8;

/**
 * 读写锁
 * Created by qucf on 2015年10月23日. 
 */
public class ReadWriteLock {

    //正在读取的线程个数
    private Integer readInteger=0;
    
    //正在写入线程的个数(最大为1)
    private Integer writeInteger=0;
    
    //正在等待获取写入锁定的线程个数
    private Integer writeWaitInteger=0;
    
    //获取写入锁定优先的话 设置为true
    private boolean writeBoolean=false;
    
    //获取读取锁的方法
    public synchronized void readlock() throws InterruptedException{
        //如果有写入操作    写入优先并且有等待写入的线程
        while(writeInteger>0 ||(writeWaitInteger>0&&writeBoolean)){
            wait();
        }
        readInteger++;
    }
    
    //释放读取锁的方法
    public synchronized void readUnLock(){
        //读取减1
        readInteger--;
        //将写入设置优先
        writeBoolean=true;
        //唤醒所有线程
        notifyAll();
    }
    
    //获取写入锁定的方法
    public synchronized void writeLock() throws InterruptedException{
        writeWaitInteger++;
        //如果有读线程或者写线程则等待
        try {
            while(readInteger>0||writeInteger>0){
                wait();
            }
        } finally{
            writeWaitInteger--;
        }
        //写入线程+1
        writeInteger++;
    }
    
    //释放写入锁
    public synchronized void writeUnLock(){
        //写入线程数-1
        writeInteger--;
        //设置优先级为false
        writeBoolean=false;
        //唤醒所有线程
        notifyAll();
    }
    
}
View Code

 

数据类

/**
 * 
 */
package com.benxq.thread8;

/**
 * 数据类
 * 持有公共数据+改公共数据的读写锁
 * Created by qucf on 2015年10月23日. 
 */
public class Data {

    //数据类持有的锁
    private final ReadWriteLock lock=new ReadWriteLock();
    
    //要访问的公共数据
    private final String[] buffer;

    public Data(int i) {
        buffer=new String[i];
        for (int a = 0; a < buffer.length; a++) {
            buffer[a]="**";
        }
    }
    
    
    public ReadWriteLock getLock() {
        return lock;
    }
    
    //读取数据的方法
    public String[] read() throws InterruptedException{
        //获取读取锁
        lock.readlock();
        try {
            Thread.sleep(1000);
            return buffer;
        } finally{
            lock.readUnLock();
        }
    }
    
    //写入操作
    public void write(String a) throws InterruptedException {
        //获取写入的suo
        lock.writeLock();
        try {
            Thread.sleep(1000);
            doWrite(a);
        } finally{
            lock.writeUnLock();
        }
    }

    //真正的写操作
    public void doWrite(String a){
        for (int i = 0; i < buffer.length; i++) {
            buffer[i]=a;
        }
    }
}
View Code

 

读线程

/**
 * 
 */
package com.benxq.thread8;

/**
 * 读线程
 * Created by qucf on 2015年10月23日. 
 */
public class ReadThread implements Runnable{
    
    private Data data;
    
    public ReadThread(Data data) {
        this.data=data;
    }

    @Override
    public void run() {
        
        while(true){
            try {
                String[] str = data.read();
                Thread.sleep(1000);
                System.out.println("["+Thread.currentThread().getName()+"]读取数据为:"+str[0]);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }

}
View Code

 

写线程

/**
 * 
 */
package com.benxq.thread8;

/**
 * 写线程 
 *  Created by qucf on 2015年10月23日. 
 */
public class WriteThread implements Runnable{

    private Data data;
    
    public WriteThread(Data data) {
        this.data=data;
    }

    @Override
    public void run() {

        while(true){
            try {
                for (int i = 0; i < 10; i++) {
                    data.write("内容"+i);
                    Thread.sleep(1000);
                    System.out.println("["+Thread.currentThread().getName()+"]写入内容为:内容"+i);
                }
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
    
}
View Code

 

主线程

/**
 * 
 */
package com.benxq.thread8;

/**
 * Created by qucf on 2015年10月23日. 
 */
public class Test {
    public static void main(String[] args) {
        //生命公共数据
        Data data=new Data(3);
        //生命读取线程
        Thread r1=new Thread(new ReadThread(data));
        Thread r2=new Thread(new ReadThread(data));
        Thread r3=new Thread(new ReadThread(data));
        
        //声明写入线程
        Thread w1=new Thread(new WriteThread(data));
        Thread w2=new Thread(new WriteThread(data));
        Thread w3=new Thread(new WriteThread(data));
        
        r1.start();
        r2.start();
        r3.start();
        w1.start();
        w2.start();
        w3.start();
    }

}
View Code

 

posted @ 2015-10-23 18:21  老瞿  阅读(315)  评论(0编辑  收藏  举报