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

原文地址:https://www.cnblogs.com/winkey4986/p/5524536.html