0

I was thinking about threads one day when I started to wonder if multiple threads can access the same information (not using synchronized(lock)) assuming they do not modify it at all.

An example would be 10 threads reading 1 class that is changing all the time due to a thread we'll call M. These threads call accessors to get information from this class but do not modify the information in any way.
Meanwhile, thread M is modifying the data inside this class occasionally (which would change the result of the calculations the 10 threads are doing once they 'restart')

Would there ever be an issue? Issue being one of those threads putting 'back' information that thread M has modified. On top of that, would there ever a be a time where accessing a piece of information would still result in Java putting the information back in memory even though it was never modified?

Thanks.

Edit: Would it be safe to call the accessor with a final before it? Like.. final Object t = someAccessor();

1 Answers1

1

No, there would not be an issue with threads reading a single, except for consistency issues occurring with read data if the write operation is not atomic, especially when multiple values are read.

Imagine that just as a thread is reading two data points (let's say an x and a y) the main thread is updating those values of X and Y. We'll say that X changes from 1 to 10 and Y changes from 2 to 20.

The following may happen:

  1. The main thread updates X to be 10.
  2. The worker thread reads X and stores it to its own memory for later processing. It sees the value 10.
  3. The worker thread then reads Y to be equal to 2 (and not 20) and stores it for later processing.
  4. The main thread updates Y to be 20.

Now, the worker thread is working on inconsistent data. If this is control for a robot arm, instead of two nice points of (1,2) and (10,20) the arm jerks to (10, 2) and causes damage. If this was a graph, random extraneous points may show up.

This occurs in spite of (and can be exacerbated on some JVMs) by the volatile keyword.

It's unlikely to happen for any given read or write(except, in the case of tight loops in both threads), but a single inconsistent read even can cause bad output, program crashes, or even severe hardware damage.

You can wrap a coodinate in a simple POJO (class with fields, constructor, getters, and setters) and swap out the coordinate atomically using AtomicReference.

Community
  • 1
  • 1
nanofarad
  • 40,330
  • 4
  • 86
  • 117
  • Ah, i completely forgot something like that could happen! Thanks for the quick reply. Is it possible to update both X and Y simultaneously so this could not happen? Or perhaps 'pause' those other threads while thread M modifies those coordinates? – TheOverWhelming May 24 '14 at 21:14
  • @TheOverWhelming Yes, it is possible to pause other threads, by using a synchronized block. If your main thread is updating X and Y in a synchronized block, threads entering a synchronized block for the same lock will "pause" until the main thread exits that block. However, then, threads will wait for each other to read. I'll edit in a better solution in my post in a few minutes – nanofarad May 24 '14 at 21:16
  • You were very thorough. One could summarize it using the term _race condition_. – keyser May 24 '14 at 21:19