程序男 2015-04-12 03:37 采纳率: 100%
浏览 1905
已采纳

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条回答 默认 最新

  • danielinbiti 2015-04-12 07:26
    关注

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

    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();//锁释放
    }
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 metadata提取的PDF元数据,如何转换为一个Excel
  • ¥15 关于arduino编程toCharArray()函数的使用
  • ¥100 vc++混合CEF采用CLR方式编译报错
  • ¥15 coze 的插件输入飞书多维表格 app_token 后一直显示错误,如何解决?
  • ¥15 vite+vue3+plyr播放本地public文件夹下视频无法加载
  • ¥15 c#逐行读取txt文本,但是每一行里面数据之间空格数量不同
  • ¥50 如何openEuler 22.03上安装配置drbd
  • ¥20 ING91680C BLE5.3 芯片怎么实现串口收发数据
  • ¥15 无线连接树莓派,无法执行update,如何解决?(相关搜索:软件下载)
  • ¥15 Windows11, backspace, enter, space键失灵