美文网首页
读写锁ReentrantReadWriteLock的使用

读写锁ReentrantReadWriteLock的使用

作者: 文景大大 | 来源:发表于2020-05-03 08:47 被阅读0次

在原先介绍的ReentrantLock的使用中,多个线程使用锁都是排他的,即上锁的代码同一时间只有一个线程可以执行。这在有些场景下是不合理,低效的。

比如我们需要有两个线程同时读某个变量的值进行一些处理,反正也没有线程会更改变量的值,不可能造成线程不安全的脏读,为什么要排他地运行呢?只有线程会更改变量的时候才需要排他。所以针对这种情况,读写锁ReentrantReadWriteLock才有了用武之地。

一、读读锁不互斥

@Slf4j
public class Counter {
    private ReentrantReadWriteLock lock = new ReentrantReadWriteLock();

    public void write() {
        lock.readLock().lock();
        try {
            log.info("当前线程{}获取了读锁!", Thread.currentThread().getName());
            // 故意等待5秒不释放锁
            Thread.sleep(5000);
        } catch (Exception e) {
            log.info("{}", e);
        } finally {
            lock.readLock().unlock();
            log.info("当前线程{}释放了读锁!", Thread.currentThread().getName());
        }
    }
}
@Slf4j
public class MyThread implements Runnable {
    private Counter counter;

    public MyThread(Counter counter){
        this.counter = counter;
    }

    @Override
    public void run() {
        counter.write();
    }
}
@Slf4j
public class Test001 {
    public static void main(String[] args) throws InterruptedException {
        Counter counter = new Counter();
        Thread thread1 = new Thread(new MyThread(counter));
        thread1.start();
        Thread thread2 = new Thread(new MyThread(counter));
        thread2.start();
    }
}

执行结果可以看出,两个线程几乎同时都获取了读锁,其中任一线程的独占时间并不影响其它线程获取读锁。

当前线程Thread-1获取了读锁!
当前线程Thread-0获取了读锁!
当前线程Thread-0释放了读锁!
当前线程Thread-1释放了读锁!

二、写写锁互斥

将上例中的读锁全部换成写锁:

    public void write() {
        lock.writeLock().lock();
        try {
            log.info("当前线程{}获取了写锁!", Thread.currentThread().getName());
            // 故意等待5秒不释放锁
            Thread.sleep(5000);
        } catch (Exception e) {
            log.info("{}", e);
        } finally {
            lock.writeLock().unlock();
            log.info("当前线程{}释放了写锁!", Thread.currentThread().getName());
        }
    }

就会发现,线程之间互斥执行:

当前线程Thread-0获取了写锁!
当前线程Thread-0释放了写锁!
当前线程Thread-1获取了写锁!
当前线程Thread-1释放了写锁!

三、其它

其它诸如读写、写读的情况,只要多线程中有获取写锁的线程,那么它与其它线程之间都是互斥的。

相关文章

网友评论

      本文标题:读写锁ReentrantReadWriteLock的使用

      本文链接:https://www.haomeiwen.com/subject/cvmuwhtx.html