java多线程的读写锁问题

package cn.fans.chapter2.six;

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

/**

  • @author fcs
  • @date 2015-4-12
  • 描述:使用读写锁实现同步访问
  • 说明:使用ReadWriteLock接口。
    */
    public class PricesInfo {
    private double price1;
    private double price2;
    private ReadWriteLock lock;
    public PricesInfo(){
    price1 = 1.0;
    price2 = 2.0;
    lock = new ReentrantReadWriteLock();
    }

    /**

    • 作者:fcs
    • 描述:使用锁机制进行读操作
    • 说明:
    • 返回:price1
    • 参数:
    • 时间:2015-4-12
      */
      public double getPrice1(){
      double value;
      lock.readLock().lock();
      try{
      value = price1;
      }finally{
      lock.readLock().unlock();
      }

      return value;
      }

    /**

    • 作者:fcs
    • 描述:使用锁机制进行读操作
    • 说明:
    • 返回:price2
    • 参数:
    • 时间:2015-4-12
      */
      public double getPrice2(){
      double value;
      lock.readLock().lock();
      try{
      value = price2;
      }finally{
      lock.readLock().unlock();
      }

      return value;
      }

    /**

    • 作者:fcs
    • 描述:使用锁机制进行写操作
    • 说明:
    • 返回:
    • 参数:price1, price2
    • 时间:2015-4-12 */ public void setPrice(double price1,double price2){ lock.writeLock().lock(); try{ this.price1 = price1; this.price2 = price2; }finally{ lock.writeLock().unlock(); } } }

package cn.fans.chapter2.six;
/**

  • @author fcs
  • @date 2015-4-12
  • 描述:读线程
  • 说明:
    */
    public class Reader implements Runnable {
    private PricesInfo pricesInfo;

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

    @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());
    }
    }
    }

package cn.fans.chapter2.six;

import java.util.concurrent.TimeUnit;

/**

  • @author fcs
  • @date 2015-4-12
  • 描述:写线程
  • 说明:
    */
    public class Writer implements Runnable {
    private PricesInfo pricesInfo;

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

    /**

    • 循环修改两个价格5次,每次修改后线程将休眠2秒钟 */ @Override public void run() { for(int i=0;i< 5;i++){ System.out.printf("Writer: Attempt to modify the prices.\n"); pricesInfo.setPrice(Math.random()*10, Math.random()*10); System.out.println("Writer:price have been modified."); try { Thread.sleep(2); } catch (InterruptedException e) { e.printStackTrace(); } } } }

package cn.fans.chapter2.six;

public class Main {
public static void main(String[] args) {
PricesInfo pricesInfo = new PricesInfo();
Reader readers[] = new Reader[5];
Thread treader [] = new Thread[5];
for(int i =0;i<5;i++){
readers [i] = new Reader(pricesInfo);
treader[i] = new Thread(readers[i]);
}

    Writer writer = new Writer(pricesInfo);
    Thread wthread = new Thread(writer);
    for(int i = 0;i < 5;i++){
        treader[i].start();
    }
    wthread.start();

}

}

图片说明
这是java并发实战手册第二章的代码,但是在我机子上运行的结果与书上不一样,写锁好像不起作用,我重新检查了代码并且运行了几遍,感觉总像读线程读了脏数据,希望有人能指点迷津。共同进步

2个回答

从原理上来说,你这打印的情况是存在的

public double getPrice1(){
double value;
lock.readLock().lock();//加锁
try{
value = price1;  //这里是1.0,
}finally{
lock.readLock().unlock();//锁释放
}
return value;//value是1.0,这时候还没有返回,其他线程,比如写进程获取锁改变了price1=0.97,然后其他线程获取锁,打印了price1 0.97。
这时该线程返回,值是1.0
}
把这种代码换一下顺序
public double getPrice1(){
lock.readLock().lock();//加锁
try{
return price1;  //这里是1.0,
}finally{
lock.readLock().unlock();//锁释放
}
}

哦,好的,不过我在并发编程网上找到答案了,给分。

Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
立即提问