• 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();
            }
        }
    }
  • 相关阅读:
    快乐来源的研究
    这可能是经历中真实的农村
    golang入门到实战教程
    免费开源pdf阅读器SumatraPDF
    农村题材光棍儿
    在线头像卡通化
    微软出品电脑管家
    刚毕业的大学生、失业的父亲:父子返乡
    ApplicationEventPublisher的简单使用
    mysql里使用JSON_EXTRACT取值
  • 原文地址:https://www.cnblogs.com/songlove/p/16179410.html
Copyright © 2020-2023  润新知