java多线程的读写锁问题

问题描述

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 : %fn",Thread.currentThread().getName(),pricesInfo.getPrice1());
    System.out.printf("%s Price 2 : %fn ",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并发实战手册第二章的代码,但是在我机子上运行的结果与书上不一样,写锁好像不起作用,我重新检查了代码并且运行了几遍,感觉总像读线程读了脏数据,希望有人能指点迷津。共同进步

解决方案

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

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();//锁释放
}
}

解决方案二:

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

解决方案三:

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

时间: 2024-10-31 04:59:59

java多线程的读写锁问题的相关文章

Java中的读/写锁

原文链接 作者:Jakob Jenkov 译者:微凉 校对:丁一 相比Java中的锁(Locks in Java)里Lock实现,读写锁更复杂一些.假设你的程序中涉及到对一些共享资源的读和写操作,且写操作没有读操作那么频繁.在没有写操作的时候,两个线程同时读一个资源没有任何问题,所以应该允许多个线程能在同时读取共享资源.但是如果有一个线程想去写这些共享资源,就不应该再有其它线程对该资源进行读或写(译者注:也就是说:读-读能共存,读-写不能共存,写-写不能共存).这就需要一个读/写锁来解决这个问题

多线程,读写锁

问题描述 请教个问题,在多线程运用中,如果只加写锁,没有加读锁,那么在写的过程中,读线程可不可以读数据. 解决方案 解决方案二:读线程可用.解决方案三:如果你不加读锁,那么就不会受到写锁的限制.也就是说读线程可以读数据.看下面我写的简单例子importjava.util.concurrent.locks.ReentrantReadWriteLock;importjava.util.concurrent.locks.Lock;publicclassTestReadWriteLock{publics

C#使用读写锁三行代码简单解决多线程并发的问题_C#教程

在开发程序的过程中,难免少不了写入错误日志这个关键功能.实现这个功能,可以选择使用第三方日志插件,也可以选择使用数据库,还可以自己写个简单的方法把错误信息记录到日志文件. 选择最后一种方法实现的时候,若对文件操作与线程同步不熟悉,问题就有可能出现了,因为同一个文件并不允许多个线程同时写入,否则会提示"文件正在由另一进程使用,因此该进程无法访问此文件". 这是文件的并发写入问题,就需要用到线程同步.而微软也给线程同步提供了一些相关的类可以达到这样的目的,本文使用到的 System.Thr

Java多线程编程中线程锁与读写锁的使用示例_java

线程锁LockLock  相当于 当前对象的 Synchronized import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; /* * Lock lock = new ReentrantLock(); * lock.lock(); lock.unLock(); * 类似于 synchronized,但不能与synchronized 混用 */ public class Lo

java多线程-读写锁原理_java

Java5 在 java.util.concurrent 包中已经包含了读写锁.尽管如此,我们还是应该了解其实现背后的原理. 读/写锁的 Java 实现(Read / Write Lock Java Implementation) 读/写锁的重入(Read / Write Lock Reentrance) 读锁重入(Read Reentrance) 写锁重入(Write Reentrance) 读锁升级到写锁(Read to Write Reentrance) 写锁降级到读锁(Write to

java多线程:并发包中ReentrantReadWriteLock读写锁的锁降级模板

写锁降级为读锁,但读锁不可升级或降级为写锁. 锁降级是为了让当前线程感知到数据的变化. 1 //读写锁 2 private ReentrantReadWriteLock lock=new ReentrantReadWriteLock(); 3 //读锁 4 private ReadLock readLock=lock.readLock(); 5 //写锁 6 private WriteLock writeLock=lock.writeLock(); 7 private boolean updat

java多线程:并发包中ReentrantReadWriteLock读写锁的原理

一:读写锁解决的场景问题--->数据的读取频率远远大于写的频率的场景,就可以使用读写锁.二:读写锁的结构--->用state一个变量.将其转化成二进制,前16位为高位,标记读线程获取锁的次数.后16位为低位,标记写线程获取锁的次数.--->读写锁需要解决的冲突:读/写冲突,写/写冲突.读/读之间无冲突.--->当有写线程获取锁的时候.state的二进制表现,低位有数字,高位全是0.当有读线程获取锁的时候,state的二进制表现,低位全是0,高位有数字.--->如何获取读线获取

java 读写锁详解

在java多线程中,为了提高效率有些共享资源允许同时进行多个读的操作,但只允许一个写的操作,比如一个文件,只要其内容不变可以让多个线程同时读,不必做排他的锁定,排他的锁定只有在写的时候需要,以保证别的线程不会看到数据不完整的文件.    下面是个关于多线程读写锁的例子,我稍微做了下修改,蛮容易理解的,来至于http://www.highya.com/redirect.php?fid=113&tid=7180&goto=nextoldset. 这里模拟了这样一个场景: 在ReadWriteL

java 可重入读写锁 ReentrantReadWriteLock 详解

读写锁 ReadWriteLock读写锁维护了一对相关的锁,一个用于只读操作,一个用于写入操作.只要没有writer,读取锁可以由多个reader线程同时保持.写入锁是独占的.互斥锁一次只允许一个线程访问共享数据,哪怕进行的是只读操作:读写锁允许对共享数据进行更高级别的并发访问:对于写操作,一次只有一个线程(write线程)可以修改共享数据,对于读操作,允许任意数量的线程同时进行读取.与互斥锁相比,使用读写锁能否提升性能则取决于读写操作期间读取数据相对于修改数据的频率,以及数据的争用--即在同一