使用读写锁实现同步数据访问
锁机制最大的改进之一就是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