Java线程同步,最佳并发实用程序,读取操作

Fat*_*ure 5 java multithreading

我有一个与java线程相关的问题.

举一个非常简单的例子,假设我有2个线程.

线程正在运行的StockReader类实例

线程B运行StockAvgDataCollector类实例

在线程B中,StockAvgDataCollector连续收集一些市场数据,进行一些重度平均/操作并更新成员变量spAvgData

在线程A中,StockReader可以使用getspAvgData()方法访问StockAvgDataCollector实例及其成员spAvgData.

因此,线程A仅执行READ操作,线程B执行READ/WRITE操作.

问题

  1. 现在,在这种情况下,我是否需要同步或原子功能或锁定或任何与并发相关的东西?如果线程A读取较旧的值无关紧要.

  2. 由于线程A仅进行READ而不更新任何内容,并且只有线程B执行任何WRITE操作,是否会出现任何死锁情况?

我在以下链接中粘贴了以下段落.从该段开始,似乎我需要担心某种锁定/同步.

http://java.sun.com/developer/technicalArticles/J2SE/concurrency/

读/写锁

使用线程从对象读取数据时,您不一定需要阻止另一个线程同时读取数据.只要线程只是读取而不是更改数据,就没有理由不能并行读取.J2SE 5.0 java.util.concurrent.locks包提供了实现此类锁定的类.ReadWriteLock接口维护一对关联的锁,一个用于只读,一个用于写入.只要没有编写器,readLock()可以由多个读取器线程同时保持.writeLock()是独占的.虽然从理论上讲,很明显使用读取器/写入器锁来增加并发性会导致性能提高而不是使用互斥锁.然而,这种性能改进只能在多处理器上完全实现,并且与被修改的数据相比,读取数据的频率以及读取和写入操作的持续时间.

哪个并发实用程序在我的示例中更便宜且更合适?

java.util.concurrent.atomic?

java.util.concurrent.locks?

java.util.concurrent.ConcurrentLinkedQueue? - 在这种情况下,StockAvgDataCollector将添加并且StockReader将删除.不会暴露getspAvgData()方法.

谢谢阿米特

cha*_*tle 3

好吧,当您有许多读者和至少一名编写者时,整个 ReadWriteLock 事情确实有意义......因此您保证了活跃性(如果没有其他线程正在写入,则不会阻塞任何读者线程)。但是,您只有两个线程。

如果您不介意线程 B 读取 spAvgData 的旧值(但未损坏),那么我会选择 AtomicDouble (或 AtomicReference,具体取决于 spAvgData 的数据类型)。

所以代码看起来像这样

public class A extends Thread {
  // spAvgData
  private final AtomicDouble spAvgData = new AtomicDouble(someDefaultValue);

  public void run() {
    while (compute) {
     // do intensive work
     // ...
      // done with work, update spAvgData
     spAvgData.set(resultOfComputation);
    }
  }

  public double getSpAvgData() {
    return spAvgData.get();
  }
}
// --------------

public class B {
  public void someMethod() {
    A a = new A();
    // after A being created, spAvgData contains a valid value (at least the default)
    a.start();
    while(read) {
      // loll around
      a.getSpAvgData();
    }
  }
}
Run Code Online (Sandbox Code Playgroud)