ReadWriteLock和ReetrantLock的区别

ReadWriteLock和ReetrantLock

  ReetrantLock是Lock框架的下的一个实现,实现对对象的锁定,用在保证线程安全,ReadWriteLock和ReetrantLock的功能类似。那么它们之间的区别是什么?以及各自使用于哪些场景。

ReadWriteLock相对于ReetrantLock的优势

  ReadWriteLock顾名思义:读写锁,当读锁占有的时候,允许别的读操作。而如果进行写操作,不允许别的线程进行读和写。例如对一个队列进行操作的时候,如果用ReetrantLock来保证线程安全的话,当读操作的时候也会阻止别的读操作,性能产生影响。

测试

  我们写代码来测试一下,看一下到底性能的影响程度。

public class RWDictionary {
    private final Map&ltString, String&gt map = new TreeMap&ltString, String&gt();

    private final ReadWriteLock lock = new ReentrantReadWriteLock();

    private final Lock readLock = lock.readLock();
    private final Lock writeLock = lock.writeLock();

    public String get(String key) {
        readLock.lock();
        try {
            try {
                Thread.sleep(10);//为了增加读操作的时间,使测试效果更好
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            return map.get(key);
        } finally {
            readLock.unlock();
        }
    }

    public void put(String key, String value) {
        writeLock.lock();
        try {
            map.put(key, value);
        } finally {
            writeLock.unlock();
        }
    }
}

  这里我们定义了一个读写锁,然后利用读写锁在读写的时候进行lock()操作来保证线程安全。

public class ReetrantLockTest {
    private final Map&ltString, String&gt map = new TreeMap&ltString, String&gt();

    private final ReentrantLock lock = new ReentrantLock();


    public String get(String key) {
        lock.lock();
        try {
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            return map.get(key);
        } finally {
            lock.unlock();
        }
    }

    public void put(String key, String value) {
        lock.lock();
        try {
            map.put(key, value);
        } finally {
            lock.unlock();
        }
    }
}

  我们在这里定义了同样的一个类,只是这次在读取数据的时候换用了ReetrantLock来进行数据的锁定。
  下面我们定义不同类的读线程。

public class RWDctionnaryTestGetThread implements  Runnable{
    private RWDictionary rwDictionary;
    public RWDctionnaryTestGetThread(RWDictionary rw){
        this.rwDictionary=rw;
    }
    public void run() {
        for(int i=0;i&lt10;i++){
            rwDictionary.get(i+"");
        }
    }
}

  在这个读线程我们读取RWDictionary。

public class DictionaryTestGetThread  implements  Runnable{
    private ReetrantLockTest reetrantLockTest;
    public DictionaryTestGetThread(ReetrantLockTest rw){
        this.reetrantLockTest=rw;
    }
    public void run() {
        for(int i=0;i&lt10;i++){
            reetrantLockTest.get(i+"");
        }
    }
}

  在这个读线程读取ReetrantLockTest。
  下面我们来写我们的测试用例:

public class RWDictionaryTest {
    public static void main(String args[]) {
        List<Thread> threadList = new ArrayList<Thread>();
        RWDictionary rwDictionary = new RWDictionary();
        long startTime = System.nanoTime();
        for (int i = 0; i < 100; i++) {

            Thread getThread = new Thread(new RWDctionnaryTestGetThread(rwDictionary));
            //  Thread putThread=new Thread(new RWDctionaryTestPutThread(rwDictionary));
            getThread.start();
            //   putThread.start();
            threadList.add(getThread);
            // threadList.add(putThread);
        }
        for (Thread thread : threadList) {
            try {
                thread.join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.println("cost time:" + (System.nanoTime() - startTime));
        threadList.clear();

        ReetrantLockTest reetrantLockTest = new ReetrantLockTest();
        startTime = System.nanoTime();
        for (int i = 0; i < 100; i++) {

            Thread getThread = new Thread(new DictionaryTestGetThread(reetrantLockTest));
            // Thread putThread=new Thread(new DictionaryTestPutThread(reetrantLockTest));
            getThread.start();
            //   putThread.start();
            threadList.add(getThread);
            //  threadList.add(putThread);
        }
        for (Thread thread : threadList) {
            try {
                thread.join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.println("cost time:" + (System.nanoTime() - startTime));
    }
}

  在上面的代码中,我们用定义了多个线程来进行测试,运行测试效果如下:
  运行结果

结论

  ReadWriteLock相对于ReetrantLock的优势在于允许多个线程同时读,可以加快速度。如果在读操作不是非常多的情况下或者读操作的时间非常短的情况下,性能差异会变小。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值