开发者

Java Thread Synchronization, best concurrent utility, read operation

I have a java threads related question.

To take a very simple example, lets say I have 2 threads.

Thread A running StockReader Class instance

Thread B running StockAvgDataCollector Class instance

In Thread B, StockAvgDataCollector collects some market Data continuously, does some heavy averaging/manipulation and update开发者_如何学JAVAs a member variable spAvgData

In Thread A StockReader has access to StockAvgDataCollector instance and its member spAvgData using getspAvgData() method.

So Thread A does READ operation only and Thread B does READ/WRITE operations.

Questions

  1. Now, do I need synchronization or atomic functionality or locking or any concurrency related stuff in this scenario? It doesnt matter if Thread A reads an older value.

  2. Since Thread A is only going READ and not update anything and only Thread B does any WRITE operations, will there be any deadlock scenarios?

I've pasted a paragraph below from the following link. From that paragraph, it seems like I do need to worry about some sort of locking/synchronizing.

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

Reader/Writer Locks

When using a thread to read data from an object, you do not necessarily need to prevent another thread from reading data at the same time. So long as the threads are only reading and not changing data, there is no reason why they cannot read in parallel. The J2SE 5.0 java.util.concurrent.locks package provides classes that implement this type of locking. The ReadWriteLock interface maintains a pair of associated locks, one for read-only and one for writing. The readLock() may be held simultaneously by multiple reader threads, so long as there are no writers. The writeLock() is exclusive. While in theory, it is clear that the use of reader/writer locks to increase concurrency leads to performance improvements over using a mutual exclusion lock. However, this performance improvement will only be fully realized on a multi-processor and the frequency that the data is read compared to being modified as well as the duration of the read and write operations.

Which concurrent utility would be less expensive and suitable in my example?

java.util.concurrent.atomic ?

java.util.concurrent.locks ?

java.util.concurrent.ConcurrentLinkedQueue ? - In this case StockAvgDataCollector will add and StockReader will remove. No getspAvgData() method will be exposed.

Thanks Amit


Well, the whole ReadWriteLock thing really makes sense when you have many readers and at least one writer... So you guarantee liveliness (you won't be blocking any reader threads if no one other thread is writing). However, you have only two threads.

If you don't mind thread B reading an old (but not corrupted) value of spAvgData, then I would go for an AtomicDouble (or AtomicReference, depending on what spAvgData's datatype).

So the code would look like this

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


Yes, synchronization is important and you need to consider two parameters: visibility of the spAvgData variable and atomicity of its update. In order to guarantee visibility of the spAvgData variable in thread B by thread A, the variable can be declared volatile or as an AtomicReference. Also you need to guard that the action of the update is atomic in case there are more invariants involved or the update action is a compound action, using synchronization and locking. If only thread B is updating that variable then you don't need synchronization and visibility should be enough for thread A to read the most up-to-date value of the variable.


  1. If you don't mind that Thread A can read complete nonsense (including partially updated data) then no, you don't need any synchronisation. However, I suspect that you should mind.
  2. If you just use a single mutex, or ReentrantReadWriteLock and don't suspend or sleep without timeout while holding locks then there will be no deadlock. If you do perform unsafe thread operations, or try to roll your own synchronisation solution, then you will need to worry about it.

If you use a blocking queue then you will also need a constantly-running ingestion loop in StockReader. ReadWriteLock is still of benefit on a single core processor - the issues are the same whether the threads are physically running at the same time, or just interleaved by context switches.

If you don't use at least some form of synchronisation (e.g. a volatile) then your reader may never see any change at all.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜