• Java线程学习之读写锁


    读写锁:

      因为读写锁分为读锁和写锁,读因为不会对数据造成改变,所以两个或多个线程的读之间不需要添加锁。而写锁不同,因为写对数据会进行改变,所以 写与写之间,读与写之间都需要加锁控制。而在重入锁中,读与读之间也会使用互斥锁,造成等待时间延长。这样的话读写锁的使用场景也就出来了,读写锁适用于读操作远比写操作的次数,这样可以提升系统性能。

    例子:

    package com.example.demo.bingfa;
    
    import java.util.Random;
    import java.util.concurrent.locks.Lock;
    import java.util.concurrent.locks.ReentrantLock;
    import java.util.concurrent.locks.ReentrantReadWriteLock;
    
    public class ReadWriteLockDemo {
        public static Lock lock = new ReentrantLock();
        public static ReentrantReadWriteLock readWriteLock = new ReentrantReadWriteLock();
        private static Lock readLock = readWriteLock.readLock();
        public static Lock writeLock = readWriteLock.writeLock();
        private int value;
        public static long readTime;
        public static  long writeTime;
        public static void main(String[] args) throws InterruptedException {
            final ReadWriteLockDemo demo = new ReadWriteLockDemo();
            Runnable readRunnale = new Runnable() {
                @Override
                public void run() {
                    try {
                        //此处传入的是读锁,如果换成重入锁,运行结果会变化很大
                        demo.handleRead(readLock);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            };
            Runnable writeRunnale = new Runnable() {
                @Override
                public void run() {
                    try {
                        //此处传入的是写锁,如果换成重入锁,将会改变
                        demo.handleWrite(writeLock, new Random().nextInt());
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            };
            long start=System.currentTimeMillis();
            for (int i = 0; i < 10; i++) {
                new Thread(readRunnale).start();
            }
            for (int i = 10; i < 20; i++) {
                    new Thread(writeRunnale).start();
            }
            //让主线程等待一段时间,确保子线程均已执行完毕
            Thread.sleep(30000);
            System.out.println("读操作耗时:" +(readTime-start)+"        写操作耗时"+(writeTime-start));
        }
    
        /**
         * 写操作处理,因为写与写之间是互斥的 ,所以每个写的线程都需要等待获得锁
         * @param writeLock
         * @param i
         * @throws InterruptedException
         */
        private void handleWrite(Lock writeLock, int i) throws InterruptedException {
            try {
                writeLock.lock();
                Thread.sleep(1000);
                value = i;
            } finally {
                writeLock.unlock();
                writeTime=System.currentTimeMillis();
            }
        }
    
        /**
         * 因为读与读之间不是互斥的所以读与读是可以并行的
         * @param readLock
         * @return
         * @throws InterruptedException
         */
        private int handleRead(Lock readLock) throws InterruptedException {
            try {
                readLock.lock();
                Thread.sleep(1000);
                return value;
            } finally {
    
                readLock.unlock();
                readTime=System.currentTimeMillis();
            }
        }
    }
  • 相关阅读:
    SSH免密码登录
    Qt编译错误GL/gl.h: No such file or directory
    UVA 11645
    《逆袭大学》文摘——9.4 基础和应用的平衡中找到大学的节奏
    EBS採购模块中的高速接收和高速接收事务
    笔记-Android中打开各种格式的文件(apk、word、excel、ppt、pdf、音视频、图片等)
    git 冲突解决的方法
    SICP 习题 (1.43)解题总结
    Swift百万线程攻破单例(Singleton)模式
    setjmp/longjmp
  • 原文地址:https://www.cnblogs.com/songlove/p/16179410.html
Copyright © 2020-2023  润新知