• JUC-ReadWriteLock


    ReadWriteLock 维护了一对相关的锁,一个用于只读操作,另一个用于写入操作。只要没有 writer,读取锁可以由多个 reader 线程同时保持。写入锁是独占的

    ReadWriteLock 读取操作通常不会改变共享资源,但执行写入操作时,必须独占方式来获取锁。

    对于读取操作占数的数据结构。ReadWriteLock 能提供比独占锁更高的并发性。

    而对于只读的数据结构,其中包含的不变性可以完全不需要考虑加锁操作

    ReadWriteLock实际上是一种乐观锁。

    对于一个线程来说,读取数据不需要线程安全,写数据需要线程安全。因此如果读操作也只能一次只有一个线程操作,那么性能就浪费了,为此有了读写锁。

    正常的锁,一次只能有一个线程操作。

    读写锁:分为读锁和写锁。

    读锁:可以多个读线程并发持有,一次能够有n多线程同时执行。

    写锁:跟普通锁一样,是独占的,一次只能有一个线程进行写操作。

    这样可以提高并发效率。

    使用场景:

    • 写写/读写 操作:需要互斥。
    • 读读操作:不需要互斥。

    初始化:

    ReadWriteLock lock = new ReentrantReadWriteLock();

    读锁上锁:

    lock.readLock().lock(); //上锁

    写锁上锁:

    lock.writeLock().lock();

    代码:

    package com.atguigu.juc;
    
    import java.util.concurrent.locks.ReadWriteLock;
    import java.util.concurrent.locks.ReentrantReadWriteLock;
    
    /*
     * 1. ReadWriteLock : 读写锁
     * 
     * 写写/读写 需要“互斥”
     * 读读 不需要互斥
     */
    public class TestReadWriteLock {
    
        public static void main(String[] args) {
            ReadWriteLockDemo rw = new ReadWriteLockDemo();
            
            new Thread(new Runnable() {
                
                @Override
                public void run() {
                    rw.set((int)(Math.random() * 101));
                }
            }, "Write:").start();
            
            for (int i = 0; i < 100; i++) {
                new Thread(new Runnable() {
                    
                    @Override
                    public void run() {
                        rw.get();
                    }
                }).start();
            }
        }
    }
    
    class ReadWriteLockDemo{
        
        private int number = 0;
        private ReadWriteLock lock = new ReentrantReadWriteLock();
        
        //
        public void get(){
    
            lock.readLock().lock(); //上锁
            try{
                System.out.println(Thread.currentThread().getName() + " : " + number);
    
            }finally{
                lock.readLock().unlock(); //释放锁
            }
        }
        
        //
        public void set(int number){
            
            lock.writeLock().lock();
            try{
                System.out.println(Thread.currentThread().getName());
                this.number = number;
            }finally{
                lock.writeLock().unlock();
            }
        }
    }
  • 相关阅读:
    LeetCode-195
    中文屋子与图灵测试谁对?
    leedcode-122
    Java 网络编程
    Java File类与IO流
    Java 异常
    Java 多线程
    Java Collection集合
    Java 常用API (第二部分)
    Java 日期时间与unix时间戳之间转换
  • 原文地址:https://www.cnblogs.com/alsf/p/9136668.html
Copyright © 2020-2023  润新知