• Post Reply Bookmark Topic Watch Topic
  • New Topic

atomicity of assignment and possible segfaults

 
Marcin Moscicki
Greenhorn
Posts: 6
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
When I started learning java (somwhere around 1.2) I remember noticing that there was no mention about atomicity of assignment. This is a well-known problem in concurrent programming, when two threads trying to assign a value to a variable may result in leaving it in a random state, that is with a final value not equal to any of them, but a merge of a two. Even more probable is a scenario when one thread tries to update a variable and a second one reads it, it may get a partially modified values. If the variable in question is a pointer, we are talking about segfaults here.

Now let's move to the java world. If the value in question is very rarely changed but heavily read, a common practice is not to synchronize around it.
This theoretically could lead to a VM crash. I know it seems improbable, and I have never encountered such a situation, but on a long-running, multi-processor server two threads will will finally try to read and write the same variable at the same time.

Anybody knows VM internals enough to answer what could happen then?
[ September 05, 2006: Message edited by: Marcin Moscicki ]
 
Jim Yingst
Wanderer
Sheriff
Posts: 18671
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Basically JVMs are required to treat reads and writes of variables in memory as atomic, unless they are longs or doubles. (Reference varables are 32 bits, so they are atomic too, just like ints, etc.) If a variable is declared volatile, then reads and writes are supposed to be atomic even if we are dealing with long or double varaibles. In practice this wasn't always the case in implementations. I'm not sure it this problem was ever fixed; I think it was, since I haven't heard anythign about it in ages, but maybe not. But anyway, as long as you're not dealing with longs or doubles, this particular problem should be a non-issue in Java. Which is not to say that you might not need synchronization or locks for some other reasons, but you shouldn't need to worry about this particular problem.
 
Edward Harned
Ranch Hand
Posts: 291
Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
If one thread writes and many threads read, then use volatile. This way the reads will always get the latest version.

If multiple threads write, use java.util.concurrent.atomic. This way your writes and reads will always be coordinated.
 
steve souza
Ranch Hand
Posts: 862
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I am reading "Java Concurrency In Practice" by Brian Goetz. On page 50-51 in section 3.5.1 he talks about 'Improper Publication". He says it is technically possible for multiple threads/cpu's to use different copies of the same variable (say an instance variable), or to have different variables referred to by this instance varialbe.

That would mean they may never be in sync. volatile and synchronized fix this problem, and possibly some of the other comments mentioned by the other poster. This very conservative approach is also helpful in that it makes you code very defensively.
 
Jim Yingst
Wanderer
Sheriff
Posts: 18671
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Well, yeah, but I thought the question was about atomicity specifically. There's a lot more stuff that can be discussed about threads in general. If you leave access to a certain variable (let's say a String) unsynchronized, and one thread changes it from a reference to "foo" a reference to "bar", then other threads may see "foo" or they may see "bar". Over time they will eventually see "bar", probably, but it may happen somewhat later than one would expect. For some applications that may be acceptable, even desireable. (Though that was true more in the early days of Java when sync was slower than it is now.) But they're never going to see a reference to some invalid pointer, which is what I understood Marcin was asking about. If they see the variable updated at all, they'll see it updated correctly, not paritally. For longs and doubles however, that's not the case (unless you use volatile, and are on a JDK >= 1.4).
 
Henry Wong
author
Sheriff
Posts: 22528
109
C++ Chrome Eclipse IDE Firefox Browser Java jQuery Linux VI Editor Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Edward Harned:
If multiple threads write, use java.util.concurrent.atomic. This way your writes and reads will always be coordinated.


Depends on what you mean by "coordinated". Volatile variables will still work with multiple writes, in that there is no chance that you will get "partial" data from the different writing threads.

The atomic library added support for a conditional write. This allows the ability to write only if a value is of a certain value. With it, we can implement increment, decrement, add, subtract, ... heck, pratically any calculation in an atomic manner.

Henry
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!