Java ReadWriteLock读写锁

看好了,我只表演一次


```java
/**
 * ReadWriteLock读写锁
 *
 * ReadWriteLock是JDK5中提供的读写分离锁。读写分离锁可以有效地帮助减少锁竞争,以提升系统性能。
 * 用锁分离的机制来提升性能非常容易理解,
 * 比如线程A1、A2、A3进行写操作,B1、B2、B3进行读操作,
 * 如果使用重入锁或者内部锁,则理论上说所有读之间、读与写之间、写和写之间都是串行操作。
 * 当B1进行读取时,B2、B3则需要等待锁。由于读操作并不对数据的完整性造成破坏,这种等待显然是不合理的。
 * 因此,读写锁就有了发挥功能的余地。
 *
 * 在这种情况下,读写锁运行多个线程同时读。
 * 但是考虑到数据完整性,写写操作和读写操作间依然是需要互相等待和持有锁的。
 * 总的来说,读写锁的访问约束如下表。
 * 读 	写
 * 读 	非阻塞 	阻塞
 * 写 	阻塞 	阻塞
 *
 * 如果在系统中,读的次数远远大于写的操作,读写锁就可以发挥最大的功效,提升系统的性能。
 *
 */
public class ReadWriteLockExample {
    
    
    /**
     * 在读锁和写锁之间的交互可以采用多种实现方式。ReadWriteLock中的一些可选实现包括:
     *
     *     释放优先:当一个写入操作释放写入锁时,并且队列中同时存在读线程和写线程,那么应该优先选择哪一个线程。
     *     读线程插队:如果锁是由读线程持有,但是写线程还在等待,是否允许新到的读线程获得访问权,还是应在写线程后面等待?
     *     若允许的话可以提高并发性但是可能造成写线程的饥饿。
     *     重入性:读取锁和写入锁是否可重入。
     *     降级和升级:若一个线程持有写锁可否在继续持有写锁的状态下获取读锁?
     *     这可能会使写锁“降级”为读锁。读锁是否优先于其它正在等待的读线程和写线程而升级为一个写锁?
     *     在大多数读写锁实现中不支持“升级”,因为这样容易死锁(两个读线程试图同时升级为写锁,那么二者都不会释放写锁)。
     */
    //创建普通重入锁
    private static Lock lock = new ReentrantLock();

    //创建读写分离锁
    private static ReentrantReadWriteLock rwlock = new ReentrantReadWriteLock();

    //创建读锁
    private static Lock readLock = rwlock.readLock();

    //创建写锁
    private static Lock writeLock = rwlock.writeLock();

    private  int value;

    public Object HandleRead(Lock lock) throws InterruptedException {
    
    
        try {
    
    
            //上锁
            lock.lock();
            //模拟处理业务
            Thread.sleep(1000);
            System.out.println(Thread.currentThread().getName() + " Read...");
            return value;
        } finally {
    
    
            //释放锁
            lock.unlock();
        }
    }

    public void HandleWrite(Lock lock,int index) throws InterruptedException {
    
    
        try {
    
    
            lock.lock();
            Thread.sleep(1000);
            value = index;
            System.out.println(Thread.currentThread().getName() + " Write...");
        }finally {
    
    
            lock.unlock();
        }
    }

    public static void main(String[] a ) throws InterruptedException {
    
    
        final ReadWriteLockExample rwle = new ReadWriteLockExample();

        //创建读方法
        Runnable readR = new Runnable() {
    
    
            @Override
            public void run() {
    
    
                try {
    
    
                    //rwle.HandleRead(lock); //普通锁
                    rwle.HandleRead(readLock);
                } catch (InterruptedException e) {
    
    
                    e.printStackTrace();
                }
            }
        };

        //创建写方法
        Runnable writeR = new Runnable() {
    
    
            @Override
            public void run() {
    
    
                try {
    
    
                    //rwle.HandleWrite(lock,new Random().nextInt()); //普通锁
                    rwle.HandleWrite(writeLock,new Random().nextInt());
                } catch (InterruptedException e) {
    
    
                    e.printStackTrace();
                }
            }
        };

        //18次读
        for (int i=0;i<18;i++){
    
    
            Thread s = new Thread(readR);
            s.start();
        }
        //2次写
        for (int i=18;i<20;i++){
    
    
            Thread s = new Thread(writeR);
            s.start();
        }

        /**
         * 结论:
         *
         * 用普通锁运行,大约执行20秒左右
         *
         * 用读写分离锁,大约执行3秒左右
         *
         */

    }

}

猜你喜欢

转载自blog.csdn.net/m0_46580493/article/details/130359838