当前位置:嗨网首页>书籍在线阅读

21-案例实现

  
选择背景色: 黄橙 洋红 淡粉 水蓝 草绿 白色 选择字体: 宋体 黑体 微软雅黑 楷体 选择字体大小: 恢复默认

案例实现

根据以下步骤实现本案例。

1.创建 PricesInfo 类,并存放两件商品的信息:

public class PricesInfo {

2.在类中声明两个 double 类型对象,分别命名为 price1price2

private double price1;
private double price2;

3.声明 ReadWriteLock 型对象,并命名为 lock

private ReadWriteLock lock;

4.在构造函数中初始化上述3个对象的值。需要补充说明的是, lock 对象指向的是 ReentrantReadWriteLock 类的对象实例:

public PricesInfo(){
  price1=1.0;
  price2=2.0;
  lock=new ReentrantReadWriteLock();
}

5.通过 getPrice1() 方法返回 price1 的值,并且使用读锁来控制对 price1 的访问:

public double getPrice1() {
  lock.readLock().lock();
  double value=price1;
  lock.readLock().unlock();
  return value;
}

6.通过 getPrice2() 方法返回 price2 的值,并且使用读锁来控制对 price2 的访问:

public double getPrice2() {
  lock.readLock().lock();
  double value=price2;
  lock.readLock().unlock();
  return value;
}

7.通过 setPrices() 方法写入两个变量的值,并且通过写锁控制线程对这两个变量的访问。为了保证有足够的时间可以观察到写锁的存在并且没有其他读锁控制的代码正在访问,我们将在函数执行过程中休眠5s:

public void setPrices(double price1, double price2) {
  lock.writeLock().lock();
  System.out.printf("%s: PricesInfo: Write Lock Adquired.\n",
                    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.\n",
                    new Date());
  lock.writeLock().unlock();
}

8.创建 Reader 类。该类实现了 Runnable 接口,并通过该类读取 PricesInfo 中的数据:

public class Reader implements Runnable {

9.声明一个 PricesInfo 类型的对象,并且在构造函数中完成对象引用的赋值:

private PricesInfo pricesInfo;
public Reader (PricesInfo pricesInfo){
  this.pricesInfo=pricesInfo;
}

10.实现 run() 方法,在该方法中将连续10次读取两个物品的价格:

@Override
public void run() {
  for (int i=0; i<20; i++){
    System.out.printf("%s: %s: Price 1: %f\n",new Date(),
                      Thread.currentThread().getName(),
                      pricesInfo.getPrice1());
    System.out.printf("%s: %s: Price 2: %f\n",new Date(),
                      Thread.currentThread().getName(),
                      pricesInfo.getPrice2());
  }
}

11.创建 Writer 类,该类实现了 Runnable 接口,并且通过该类修改 PricesInfo 中的变量属性:

public class Writer implements Runnable {

12.声明 PricesInfo 型对象,并在该类的构造函数中完成初始化:

private PricesInfo pricesInfo;
public Writer(PricesInfo pricesInfo){
  this.pricesInfo=pricesInfo;
}

13.实现 run() 方法,该方法连续3次修改两个商品的价格并在每次修改后休眠2s:

@Override
public void run() {
  for (int i=0; i<3; i++) {
    System.out.printf("%s: Writer: Attempt to modify the
                      prices.\n", new Date());
    pricesInfo.setPrices(Math.random()*10, Math.random()*8);
    System.out.printf("%s: Writer: Prices have been
                      modified.\n", new Date());
    try {
      Thread.sleep(2);
    } catch (InterruptedException e) {
      e.printStackTrace();
    } 
  }
}

14.通过产生名为 Main 的主类并添加 main() 方法实现一个主类:

public class Main {
  public static void main(String[] args) {

15.创建 PricesInfo 类型的对象:

PricesInfo pricesInfo=new PricesInfo();

16.创建5个线程,并传入 Reader 对象实例:

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

17.单独创建一个线程并传入 Writer 对象实例:

Writer writer=new Writer(pricesInfo);
Thread  threadWriter=new Thread(writer);

18.启动以上所有线程:

for (int i=0; i<5; i++){
  threadsReader[i].start();
}
threadWriter.start();