多线程-ReentrantReadWriteLock

ReentrantLock具有完全互斥排他的效果,即同一时间只有一个线程在执行ReentrantLock.lock()方法后面的任务。这样做虽然保证了实例变量的线程安全,但效率却是非常低下的。JDK中提供了一个读写锁ReentrantReadWriteLock,使用它可以加快运行效率,在某些不需要操作实例变量的方法中,完全可以使用读写锁ReentrantReadWriteLock来提升该方法的代码运行速度。 
读写锁有两个锁:读锁和写锁,读锁也称为共享锁,写锁称为排他锁。也就是多个读锁之间不互斥,读锁与写锁互斥,写锁与写锁互斥。

package org.github.lujiango;

import java.util.concurrent.locks.ReentrantReadWriteLock;

public class Test09 {

    static class Service {
        private ReentrantReadWriteLock lock = new ReentrantReadWriteLock();

        public void read() {
            try {
                lock.readLock().lock();
                System.out.println("get read lock: " + Thread.currentThread().getName());
                Thread.sleep(10000);
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                lock.readLock().unlock();
            }
        }

        public void write() {
            try {
                lock.writeLock().lock();
                System.out.println("get write lock: " + Thread.currentThread().getName());
                Thread.sleep(10000);
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                lock.writeLock().unlock();
            }
        }
    }

    static class ThreadReader extends Thread {
        private Service service;

        public ThreadReader(Service service) {
            this.service = service;
        }

        @Override
        public void run() {
            service.read();
        }
    }

    static class ThreadWriter extends Thread {
        private Service service;

        public ThreadWriter(Service service) {
            this.service = service;
        }

        @Override
        public void run() {
            service.write();
        }
    }

    public static void main(String[] args) {
        Service service = new Service();
        // (1) 读读
        ThreadReader r1 = new ThreadReader(service);
        ThreadReader r2 = new ThreadReader(service);
        r1.start();
        r2.start();
        // (2) 写写
        ThreadWriter w1 = new ThreadWriter(service);
        ThreadWriter w2 = new ThreadWriter(service);
        w1.start();
        w2.start();
    }

}

总结:读写,写读,写写都是互斥的;而读读是异步的,非互斥的。

posted @ 2017-09-23 14:00  小路不懂2  阅读(267)  评论(0编辑  收藏  举报