zoukankan      html  css  js  c++  java
  • ReentrantReadWriteLock锁例子

    锁所提供的最重要的改进之一就是ReadWriteLock接口和唯一 一个实现它的ReentrantReadWriteLock类。这个类提供两把锁,一把用于读操作和一把用于写操作。同时可以有多个线程执行读操作,但只有一个线程可以执行写操作。当一个线程正在执行一个写操作,不可能有任何线程执行读操作。

    参考http://ifeve.com/basic-thread-synchronization-6/#more-7030 做了优化的例子
    创建了5个读线程、一个写线程,分别读10次、写3次

    PricesInfo

    package threadTest.reentrantReadWriteLockTest;
    
    import java.util.concurrent.locks.ReadWriteLock;
    import java.util.concurrent.locks.ReentrantReadWriteLock;
    
    
    public class PricesInfo {
        private double price1;
        private double price2;
    
        private ReadWriteLock lock;
    
        public PricesInfo() {
            this.price1 = 1.0;
            this.price2 = 2.0;
            this.lock = new ReentrantReadWriteLock();
        }
    
        public double getPrice1() {
            lock.readLock().lock();
            System.out.printf("%s : Price1 开始读了!
    " ,Thread.currentThread().getName());
            double value = price1;
            System.out.printf("%s : Price1 读取完毕 : %f
    "
                    ,Thread.currentThread().getName(),value);
            lock.readLock().unlock();
            return value;
        }
    
        public double getPrice2() {
            lock.readLock().lock();
            System.out.printf("%s : Price2开始读了!
    " ,Thread.currentThread().getName());
            double value = price2;
            System.out.printf("%s : Price2读取完毕 : %f
    "
                    ,Thread.currentThread().getName(),value);
            lock.readLock().unlock();
            return value;
        }
    
        public void setPrices(double price1, double price2) {
            lock.writeLock().lock();
            System.out.printf("Writer:Attempt to modify the price.
    ");
            this.price2 = price2;
            this.price1 = price1;
    
            System.out.printf("Writer:Prices have been modified.
    ");
            lock.writeLock().unlock();
    
        }
    
    }
    Reader
    package threadTest.reentrantReadWriteLockTest;
    
    
    public class Reader implements Runnable {
        private PricesInfo priceInfo;
    
        public Reader(PricesInfo priceInfo) {
            this.priceInfo = priceInfo;
        }
    
        @Override
        public void run() {
            for (int i = 0; i < 10; i++) {
                priceInfo.getPrice1();
                priceInfo.getPrice2();
                try {
                    Thread.sleep(2);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    Writer

    package threadTest.reentrantReadWriteLockTest;
    
    public class Writer implements Runnable {
        private PricesInfo pricesInfo;
    
        public Writer(PricesInfo pricesInfo) {
            this.pricesInfo = pricesInfo;
        }
    
        @Override
        public void run() {
            for (int i = 0; i < 3; i++) {
                pricesInfo.setPrices((i+1)* 10, (i+1) * 100);
                try {
                    Thread.sleep(2);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    main函数

    package threadTest.reentrantReadWriteLockTest;
    
    public class App1 {
        public static void main(String[] args) {
            PricesInfo pricesInfo = new PricesInfo();
            Reader[] readers = new Reader[5];
            Thread[] threadsReader = new Thread[5];
            for (int i = 0; i < 5; i++) {
                readers[i] = new Reader(pricesInfo);
                threadsReader[i] = new Thread(readers[i]);
            }
            Writer writer = new Writer(pricesInfo);
            Thread threadWriter = new Thread(writer);
            for (int i = 0; i < 5; i++) {
                threadsReader[i].start();
            }
            threadWriter.start();
        }
    }

    结果如下

    使用ReentrantReadWriteLock,同时可以有多个线程执行读操作,但只有一个线程可以执行写操作

  • 相关阅读:
    解决Scala Play框架在Git Bash运行的异常:Could not find configuration file ../framework/sbt/sbt.boot.properties
    Envoy的线程模型[翻译]
    解决Minikube start卡住的方法
    Jade To Pug过程中的一个小问题
    python如何获取变量的变量名
    python数字图像处理(五) 图像的退化和复原
    从1<2<3的语法糖说起
    在CNN上增加一层CAM告诉你CNN到底关注什么
    python数字图像处理(四) 频率域滤波
    windows linux子系统(Windows Subsystem for Linux)的存放目录
  • 原文地址:https://www.cnblogs.com/winkey4986/p/5524536.html
Copyright © 2011-2022 走看看