• 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,同时可以有多个线程执行读操作,但只有一个线程可以执行写操作

  • 相关阅读:
    再次或多次格式化导致namenode的ClusterID和datanode的ClusterID之间不一致的问题解决办法
    Linux安装aria2
    POJ 3335 Rotating Scoreboard 半平面交
    hdu 1540 Tunnel Warfare 线段树 区间合并
    hdu 3397 Sequence operation 线段树 区间更新 区间合并
    hud 3308 LCIS 线段树 区间合并
    POJ 3667 Hotel 线段树 区间合并
    POJ 2528 Mayor's posters 贴海报 线段树 区间更新
    POJ 2299 Ultra-QuickSort 求逆序数 线段树或树状数组 离散化
    POJ 3468 A Simple Problem with Integers 线段树成段更新
  • 原文地址:https://www.cnblogs.com/winkey4986/p/5524536.html
Copyright © 2020-2023  润新知