Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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 updates 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

like image 699
FatherFigure Avatar asked Feb 08 '11 23:02

FatherFigure


People also ask

What will happen if two threads try to read same resource without synchronization in Java?

When more than one thread try to access same resource without synchronization causes race condition. So we can solve race condition by using either synchronized block or synchronized method. When no two threads can access same resource at a time phenomenon is also called as mutual exclusion.

What is the fastest and most thread-safe way of updating an object a?

Use copy on write if you want to update a graph of objects or a collection, and the threads mostly read and only rarely update.

Are Java threads concurrent or parallel?

A thread is only executing one task at a time. There is no parallel execution of tasks going in parallel threads/CPUs. An application can also be parallel but not concurrent.


3 Answers

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();
    }
  }
}
like image 71
chahuistle Avatar answered Oct 18 '22 19:10

chahuistle


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.

like image 29
dimitrisli Avatar answered Oct 18 '22 20:10

dimitrisli


  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.

like image 2
OrangeDog Avatar answered Oct 18 '22 21:10

OrangeDog