Java并发编程实例--17.使用read/write锁同步数据访问

锁机制带来的最有意义的改进是提供了ReadWriteLock接口及其实现类ReentrantReadWriteLock。
这个类有2个锁,一个针对读操作另一个针对写操作。
可以有多个线程使用读操作,但是只有一个线程使用写操作。
当一个线程做写操作时,不能有任何线程做读操作。


本例中,我们将学习如何通过ReadWriteLock接口实现一个对2个产品价格的访问进行控制。


PricesInfo.java

package com.dylan.thread.ch2.c05.task;

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

/**
 * This class simulates the store of two prices. We will
 * have a writer that stores the prices and readers that 
 * consult this prices
 *
 */
public class PricesInfo {
	
	/**
	 * The two prices
	 */
	private double price1;
	private double price2;
	
	/**
	 * Lock to control the access to the prices
	 */
	private ReadWriteLock lock;
	
	/**
	 * Constructor of the class. Initializes the prices and the Lock
	 */
	public PricesInfo(){
		price1=1.0;
		price2=2.0;
		lock=new ReentrantReadWriteLock();
	}

	/**
	 * Returns the first price
	 * @return the first price
	 */
	public double getPrice1() {
		lock.readLock().lock();
		double value=price1;
		lock.readLock().unlock();
		return value;
	}

	/**
	 * Returns the second price
	 * @return the second price
	 */
	public double getPrice2() {
		lock.readLock().lock();
		double value=price2;
		lock.readLock().unlock();
		return value;
	}

	/**
	 * Establish the prices
	 * @param price1 The price of the first product
	 * @param price2 The price of the second product
	 */
	public void setPrices(double price1, double price2) {
		lock.writeLock().lock();
		this.price1=price1;
		this.price2=price2;
		lock.writeLock().unlock();
	}
}

Reader.java

package com.dylan.thread.ch2.c05.task;

/**
 * This class implements a reader that consults the prices
 *
 */
public class Reader implements Runnable {

	/**
	 * Class that stores the prices
	 */
	private PricesInfo pricesInfo;
	
	/**
	 * Constructor of the class
	 * @param pricesInfo object that stores the prices
	 */
	public Reader (PricesInfo pricesInfo){
		this.pricesInfo=pricesInfo;
	}
	
	/**
	 * Core method of the reader. Consults the two prices and prints them
	 * to the console
	 */
	@Override
	public void run() {
		for (int i=0; i<10; i++){
			System.out.printf("%s: Price 1: %f\n",Thread.currentThread().getName(),pricesInfo.getPrice1());
			System.out.printf("%s: Price 2: %f\n",Thread.currentThread().getName(),pricesInfo.getPrice2());
		}
	}

}

Writer.java

package com.dylan.thread.ch2.c05.task;

/**
 * This class implements a writer that establish the prices
 *
 */
public class Writer implements Runnable {

	/**
	 * Class that stores the prices
	 */
	private PricesInfo pricesInfo;
	
	/**
	 * Constructor of the class
	 * @param pricesInfo object that stores the prices
	 */
	public Writer(PricesInfo pricesInfo){
		this.pricesInfo=pricesInfo;
	}
	
	/**
	 * Core method of the writer. Establish the prices
	 */
	@Override
	public void run() {
		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.printf("Writer: Prices have been modified.\n");
			try {
				Thread.sleep(2);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}

}

Main.java

package com.dylan.thread.ch2.c05.core;


import com.dylan.thread.ch2.c05.task.PricesInfo;
import com.dylan.thread.ch2.c05.task.Reader;
import com.dylan.thread.ch2.c05.task.Writer;

/**
 * Main class of the example
 *
 */
public class Main {

	/**
	 * Main class of the example
	 * @param args
	 */
	public static void main(String[] args) {

		// Creates an object to store the prices
		PricesInfo pricesInfo=new PricesInfo();
		
		Reader readers[]=new Reader[5];
		Thread threadsReader[]=new Thread[5];
		
		// Creates five readers and threads to run them
		for (int i=0; i<5; i++){
			readers[i]=new Reader(pricesInfo);
			threadsReader[i]=new Thread(readers[i]);
		}
		
		// Creates a writer and a thread to run it
		Writer writer=new Writer(pricesInfo);
		Thread threadWriter=new Thread(writer);
		
		// Starts the threads
		for (int i=0; i<5; i++){
			threadsReader[i].start();
		}
		threadWriter.start();
		
	}

}


运行结果:

Thread-0: Price 1: 1.000000
Thread-3: Price 1: 1.000000
Thread-3: Price 2: 2.000000
Thread-3: Price 1: 1.000000
Thread-3: Price 2: 2.000000
Thread-3: Price 1: 1.000000
Thread-3: Price 2: 2.000000
Thread-3: Price 1: 1.000000
Thread-3: Price 2: 2.000000
Thread-3: Price 1: 1.000000
Thread-3: Price 2: 2.000000
Writer: Attempt to modify the prices.
Thread-3: Price 1: 1.000000
Thread-3: Price 2: 1.280423
Thread-3: Price 1: 3.047936

...

猜你喜欢

转载自blog.csdn.net/indexman/article/details/80304154
今日推荐