Follow these steps to implement the example:
- Create a class named PricesInfo that stores information about the prices of two products:
public class PricesInfo {
- Declare two double attributes named price1 and price2:
private double price1;
private double price2;
- Declare a ReadWriteLock object called lock:
private ReadWriteLock lock;
- Implement the constructor of the class that initializes the three attributes. For the lock attribute, create a new ReentrantReadWriteLock object:
public PricesInfo(){
price1=1.0;
price2=2.0;
lock=new ReentrantReadWriteLock();
}
- Implement the getPrice1() method that returns the value of the price1 attribute. It uses the read lock to control access to the value of this attribute:
public double getPrice1() {
lock.readLock().lock();
double value=price1;
lock.readLock().unlock();
return value;
}
- Implement the getPrice2() method that returns the value of the price2 attribute. It uses the read lock to control access to the value of this attribute:
public double getPrice2() {
lock.readLock().lock();
double value=price2;
lock.readLock().unlock();
return value;
}
- Implement the setPrices() method that establishes the values of two attributes. It uses the write lock to control access to them. We are going to make the thread sleep for 5 seconds. This shows that even though it has the write lock, there are no other threads getting the read lock:
public void setPrices(double price1, double price2) {
lock.writeLock().lock();
System.out.printf("%s: PricesInfo: Write Lock Adquired. ",
new Date());
try {
TimeUnit.SECONDS.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
this.price1=price1;
this.price2=price2;
System.out.printf("%s: PricesInfo: Write Lock Released. ",
new Date());
lock.writeLock().unlock();
}
- Create a class named Reader and specify that it implements the Runnable interface. This class implements a reader of the values of the PricesInfo class attribute:
public class Reader implements Runnable {
- Declare a PricesInfo object and implement the constructor of the class that could initialize this object:
private PricesInfo pricesInfo;
public Reader (PricesInfo pricesInfo){
this.pricesInfo=pricesInfo;
}
- Implement the run() method for this class. It reads the value of the two prices 10 times:
@Override
public void run() {
for (int i=0; i<20; i++){
System.out.printf("%s: %s: Price 1: %f ",new Date(),
Thread.currentThread().getName(),
pricesInfo.getPrice1());
System.out.printf("%s: %s: Price 2: %f ",new Date(),
Thread.currentThread().getName(),
pricesInfo.getPrice2());
}
}
- Create a class named Writer and specify that it implements the Runnable interface. This class implements a modifier of the values of the PricesInfo class attribute:
public class Writer implements Runnable {
- Declare a PricesInfo object and implement the constructor of the class that could initialize this object:
private PricesInfo pricesInfo;
public Writer(PricesInfo pricesInfo){
this.pricesInfo=pricesInfo;
}
- Implement the run() method. It modifies the value of the two prices that are sleeping for 2 seconds between modifications three times:
@Override
public void run() {
for (int i=0; i<3; i++) {
System.out.printf("%s: Writer: Attempt to modify the
prices. ", new Date());
pricesInfo.setPrices(Math.random()*10, Math.random()*8);
System.out.printf("%s: Writer: Prices have been
modified. ", new Date());
try {
Thread.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
- Implement the main class of the example by creating a class named Main and adding the main() method to it:
public class Main {
public static void main(String[] args) {
- Create a PricesInfo object:
PricesInfo pricesInfo=new PricesInfo();
- Create five Reader objects and five Thread objects to execute them:
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]);
}
- Create a Writer object and Thread to execute it:
Writer writer=new Writer(pricesInfo);
Thread threadWriter=new Thread(writer);
- Start the threads:
for (int i=0; i<5; i++){
threadsReader[i].start();
}
threadWriter.start();