使用读写锁实现同步数据访问

  锁机制最大的改进之一就是ReadWriteLock接口和它的唯一实现类ReentrantReadWriteLock。这个类有两个锁,一个是读操作锁,另一个是写操作锁。使用读操作锁时可以允许多个线程同时访问,但是使用写操作锁时只允许一个线程进行。在一个线程执行写操作时,其他线程不能够执行读操作。

  下面我们将通过范例学习如何使用ReadWriteLock接口编写程序。这个范例将使用ReadWriteLock接口控制对价格对象的访问,价格对象存储了两个产品的价格。

1. 创建一个价格信息类PricesInfo,并且存放两个产品的价格。

import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;


public class PricesInfo {
    //两个价格
    private double price1;
    private double price2;
    //声明读写锁ReadWriteLock对象lock
    private ReadWriteLock lock;
    public PricesInfo(){
        price1 = 1.0;
        price2 = 2.0;
        lock = new ReentrantReadWriteLock();
    }
    
    public double getPrice1(){
        lock.readLock().lock();
        double value = price1;
        lock.readLock().unlock();
        return value;
    }
    
    public double getPrice2()
    {
        lock.readLock().lock();
        double value = price2;
        lock.readLock().unlock();
        return value;
    }
    
    public void setPrices(double price1, double price2){
        lock.writeLock().lock();
        this.price1 = price1;
        this.price2 = price2;
        lock.writeLock().unlock();
    }
    
}

2. 创建读取类Reader,它实现了Runnable接口。

public class Reader implements Runnable {
    private PricesInfo pricesInfo;
    public Reader(PricesInfo pricesInfo){
        this.pricesInfo = pricesInfo;
    }
    @Override
    public void run() {
        // 循环读取连个价格10次
        for(int i=0;i<10;i++){
            System.out.printf("%s: Price1: %f\n", Thread.currentThread().getName(), pricesInfo.getPrice1());
            System.out.printf("%s: Price2: %f\n", Thread.currentThread().getName(), pricesInfo.getPrice2());
        }

    }

}

3. 创建写入类Writer,它实现了Runnable接口。

public class Writer implements Runnable {
    private PricesInfo pricesInfo;
    public Writer(PricesInfo pricesInfo){
        this.pricesInfo = pricesInfo;
    }
    @Override
    public void run() {
        // 循环修改两个价格3次
        try {
            for(int i=0;i<3;i++){
                System.out.printf("Writer: Attempt to modify the prices.\n");
                pricesInfo.setPrices(Math.random()*10, Math.random()*8);
                System.out.println("Writer: Prices have been modified.");
                Thread.sleep(2);
            }
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }

}

4. 创建范例的主类Main

public class Main {

    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();
    }
}

5. 程序运行结果如下

Thread-1: Price1: 1.000000
Thread-4: Price1: 1.000000
Thread-2: Price1: 1.000000
Thread-2: Price2: 2.000000
Thread-2: Price1: 1.000000
Thread-2: Price2: 2.000000
Thread-0: Price1: 1.000000
Thread-0: Price2: 2.000000
Thread-0: Price1: 1.000000
Thread-0: Price2: 2.000000
Thread-0: Price1: 1.000000
Thread-0: Price2: 2.000000
Thread-0: Price1: 1.000000
Thread-0: Price2: 2.000000
Thread-0: Price1: 1.000000
Thread-0: Price2: 2.000000
Thread-0: Price1: 1.000000
Thread-0: Price2: 2.000000
Thread-0: Price1: 1.000000
Thread-0: Price2: 2.000000
Thread-0: Price1: 1.000000
Thread-0: Price2: 2.000000
Thread-0: Price1: 1.000000
Thread-0: Price2: 2.000000
Thread-0: Price1: 1.000000
Thread-0: Price2: 2.000000
Thread-2: Price1: 1.000000
Thread-2: Price2: 2.000000
Writer: Attempt to modify the prices.
Writer: Prices have been modified.
Thread-3: Price1: 1.000000
Thread-3: Price2: 4.840562
Thread-1: Price2: 2.000000
Thread-1: Price1: 6.220535
Thread-1: Price2: 4.840562
Thread-1: Price1: 6.220535
Thread-1: Price2: 4.840562
Thread-1: Price1: 6.220535
Thread-1: Price2: 4.840562
Thread-1: Price1: 6.220535
Thread-1: Price2: 4.840562
Thread-1: Price1: 6.220535
Thread-1: Price2: 4.840562
Thread-1: Price1: 6.220535
Thread-1: Price2: 4.840562
Thread-1: Price1: 6.220535
Thread-1: Price2: 4.840562
Thread-1: Price1: 6.220535
Thread-1: Price2: 4.840562
Thread-1: Price1: 6.220535
Thread-1: Price2: 4.840562
Writer: Attempt to modify the prices.
Writer: Prices have been modified.
Thread-4: Price2: 2.000000
Thread-4: Price1: 5.640719
Thread-4: Price2: 1.872038
Thread-4: Price1: 5.640719
Thread-4: Price2: 1.872038
Thread-2: Price1: 6.220535
Thread-2: Price2: 1.872038
Thread-2: Price1: 5.640719
Thread-2: Price2: 1.872038
Thread-2: Price1: 5.640719
Thread-2: Price2: 1.872038
Thread-2: Price1: 5.640719
Thread-2: Price2: 1.872038
Thread-2: Price1: 5.640719
Thread-2: Price2: 1.872038
Thread-2: Price1: 5.640719
Thread-2: Price2: 1.872038
Thread-2: Price1: 5.640719
Thread-2: Price2: 1.872038
Thread-3: Price1: 5.640719
Thread-3: Price2: 1.872038
Thread-3: Price1: 5.640719
Thread-3: Price2: 1.872038
Thread-3: Price1: 5.640719
Thread-3: Price2: 1.872038
Thread-3: Price1: 5.640719
Thread-3: Price2: 1.872038
Thread-3: Price1: 5.640719
Thread-3: Price2: 1.872038
Thread-3: Price1: 5.640719
Thread-3: Price2: 1.872038
Thread-3: Price1: 5.640719
Thread-3: Price2: 1.872038
Thread-3: Price1: 5.640719
Thread-3: Price2: 1.872038
Thread-3: Price1: 5.640719
Thread-3: Price2: 1.872038
Writer: Attempt to modify the prices.
Writer: Prices have been modified.
Thread-4: Price1: 5.491746
Thread-4: Price2: 2.729420
Thread-4: Price1: 5.491746
Thread-4: Price2: 2.729420
Thread-4: Price1: 5.491746
Thread-4: Price2: 2.729420
Thread-4: Price1: 5.491746
Thread-4: Price2: 2.729420
Thread-4: Price1: 5.491746
Thread-4: Price2: 2.729420
Thread-4: Price1: 5.491746
Thread-4: Price2: 2.729420
Thread-4: Price1: 5.491746
Thread-4: Price2: 2.729420

 

posted @ 2015-10-24 15:28  ~风轻云淡~  阅读(353)  评论(1编辑  收藏  举报