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