天天看点

Java多线程探究-读写锁ReentrantReadWriteLock

读写锁实际是一种特殊的自旋锁,它把对共享资源的访问者划分成读者和写者,读者只对共享资源进行读访问,写者则需要对共享资源进行写操作。这种锁相对于自旋锁而言,能提高并发性,因为在多处理器系统中,它允许同时有多个读者来访问共享资源,最大可能的读者数为实际的逻辑CPU数。写者是排他性的,一个读写锁同时只能有一个写者或多个读者(与CPU数相关),但不能同时既有读者又有写者

读写锁的场景

如果很多线程从一个数据结构读取数据而很少从线程修改其中数据的话,读写锁是十分有用的。在这种情况下,允许对读的线程共享访问时合适的。当然写的线程依然必须是互斥访问的

Java多线程探究-读写锁ReentrantReadWriteLock

ReentrantReadWriteLock是Java的一个读写锁类

ReentrantReadWriteLock.ReadLock readLock()

返回用于读取操作的锁

ReentrantReadWriteLock.WriteLock writeLock()

返回用于写入操作的锁

读锁:不排斥读锁,排斥写锁

写锁:排斥其他的写锁和读锁

class FileObj{
    public String context ;

    public String getContext() {
        return context;
    }

    public void setContext(String context) {
        this.context = context;
    }
}
class ReadThread extends Thread{
    private FileObj fileObj;
    private ReentrantReadWriteLock.ReadLock lock;
    public  ReadThread(FileObj obj , ReentrantReadWriteLock.ReadLock lock){
        this.lock = lock;
        this.fileObj = obj;
    }
    @Override
    public void run(){

        while(true){
            lock.lock();
            try{
                System.out.println(getName()+" 读取 "+ fileObj.getContext());
                try {
                    Thread.sleep();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }finally {
                lock.unlock();
            }
        }


    }
}
class WriteThread extends  Thread{
    Random random = new Random();
    private FileObj fileObj;
    private ReentrantReadWriteLock.WriteLock lock;
    private String[] str = {"Hello Java","Year Spark","Ok Flume"};
    public  WriteThread(FileObj obj , ReentrantReadWriteLock.WriteLock lock){
        this.lock = lock;
        this.fileObj = obj;
    }
    @Override
    public void run() {
        while (true) {
        lock.lock();
        try {

            String tmp = str[random.nextInt()];
            System.out.println(getName() + " 写 " + tmp);
            fileObj.setContext(tmp);
            try {
                Thread.sleep();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        } finally {
            lock.unlock();
        }
    }
    }
}
public class ReadAndWriteTest {
    public static void main(String[] args) {

        ExecutorService executorService = Executors.newFixedThreadPool();
        ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
        FileObj obj  =  new FileObj();
        obj.setContext("Hello....");
        Thread r1 = new ReadThread(obj,lock.readLock());
        Thread r2 = new ReadThread(obj,lock.readLock());
        Thread r3 = new ReadThread(obj,lock.readLock());

        WriteThread w1 = new WriteThread(obj,lock.writeLock());
        WriteThread w2 = new WriteThread(obj,lock.writeLock());
        WriteThread w3 = new WriteThread(obj,lock.writeLock());

        executorService.execute(r1);
        executorService.execute(r2);
        executorService.execute(r3);
        executorService.execute(w1);
       /* executorService.execute(w1);
        executorService.execute(w3);*/

        executorService.shutdown();


    }
}
           

输出结果

Java多线程探究-读写锁ReentrantReadWriteLock