Discussing this answer I was wondered why didn't we use sychronization when assigning default values.
class StateHolder {
private int counter = 100;
private boolean isActive = false;
public synchronized void resetCounter() {
counter = 0;
isActive = true;
}
public synchronized void printStateWithLock() {
System.out.println("Counter : " + counter);
System.out.println("IsActive : " + isActive);
}
public void printStateWithNoLock() {
System.out.println("Counter : " + counter);
System.out.println("IsActive : " + isActive);
}
}
This class looks thread safe because access to its fields is managed by a synchronized method. That way, all we have to do is to publish it safely. For instance:
public final StateHolder stateHolder = new StateHolder();
Can it be considered as a safe publication? I think no, it cannot. Consulting the final field semantic (emphasized mine) I figured out that the only thing guarnteeed is that stateHolder reference is not a stale one. :
A thread that can only see a reference to an object after that object
has been completely initialized is guaranteed to see the correctly
initialized values for that object's final fields.
final field semantic is not concerned about the state of the ojbect referenced to by the final field. That way, another thread might as well see default values of the fields.
QUESTION: How can we guarantee memory consistency of the filed's values assigned within a constructor or instance initializer?
I think we have to declare them either volatile or final as that there is no happens-before relationship bethween assigning a reference and constructor invocation. But lots of library classes does not declare fields that way. java.lang.String is an example:
public final class String
implements java.io.Serializable, Comparable<String>, CharSequence{
//...
private int hash; //neither final nor volatile
//...
}
final can guarantee you that you'll see the assigned value to an instance variable after the instance construction without the need of any further action. You just need to make sure that you don't leak the constructed instance within the constructor.
volatile can also guarantee you that you'll see the default value that you set for some instance variable, because the instance variable initializers are guaranteed to be executed before the end of the constructor per JLS 12.5 Creation of New Class Instances.
Safe publication is not entirely trivial, but if you stick with one of the popular mechanisms for achieving it, you should be perfectly fine. You can take a look at Safe Publication and Safe Initialization in Java for some more interesting details.
As for String.hash, it's a popular example of the so-called benign data races. The accesses to the hash instance variable allow both racing of a read and write and racing of two writes. To illustrate just the latter, two threads can simultaneously:
see the initial value of 0
decide that they are the first to calculate the hash
calculate the hash code and write to the same variable without any synchronization
The race was still allowed and considered to be benign because of two reasons:
Hash code calculation for the immutable String instances is an idempotent operation.
Writes of 32-bit values are guaranteed not to tear.
Even benign data races are still not recommended though. See Benign data races: what could possibly go wrong? or Nondeterminism is unavoidable, but data races are pure evil.
Related
Please consider following code snippet.
public class Visibility {
private volatile SomeData data;
public static class SomeData {
private int number;
public SomeData(int number) {
this.number = number;
}
public int getNumber() {
return number;
}
}
public void initialize() {
data = new SomeData(42);
}
public SomeData getData() {
return data;
}
}
If number field was final, any thread that sees data reference is not null (after other thread called initialize) is also guaranteed to see number field value as 42.
Do we have the same guarantees for non final field?
In other words, is it possible for some thread to observe non-null
data reference, but number field as 0?
Thanks in advance!
It is not possible for some thread to observe non-null data reference, but number field as 0.
See the doc of volatile:
This means that changes to a volatile variable are always visible to
other threads. What's more, it also means that when a thread reads a
volatile variable, it sees not just the latest change to the volatile,
but also the side effects of the code that led up the change.
So when you get a non-null data, it must have been successfully initiated, the number must be non-zero.
In general, yes, it is possible to see a field in a partially constructed state if the field is not published in a safe manner. In the particular case of your question, the volatile keyword is a satisfactory form of safe publication. According to Java Concurrency in Practice:
To publish an object safely, both the reference to the object and the
object's state must be made visible to other threads at the same time.
A properly constructed object can be safely published by:
Initializing an object reference from a static initializer.
Storing a reference to it into a volatile field.
Storing a reference to it into a final field.
Storing a reference to it into a field that is properly guarded by a (synchronized) lock.
For more information, see the following:
Does a volatile reference really guarantee that the inner state of the object is visible to other threads?
Java multi-threading & Safe Publication
Java Concurrency in Practice
I am recently reading the book "Java Concurrency in Practice". One example of "safe publish" it gives is to initialize a private int field n during construction, and a later assertion on that field n == "expect value" through a public method could still be failed if it is called from another thread. This makes me feel worried in that, assuming all private fields are initialized only once, do we still have to mark them as volatile or wrap them into ThreadLocal or even use an AtomicReference to get a pure thread safe java class, since these private fields, though not visible outside, definitely could be referenced by the method(s) called by other threads.
EDIT: Just to be clear - the assertion is failed because the calling thread sees a stale value of n, even though it has been set during construction. This is a clearly a memory-visibility issue. Problem is whether synchronizing on n is worthy of the overhead after all, since it is only initialized once, and as a private field, author can make sure it won't be changed again.
This specific case is properly documented in the JSR 133: Java Memory Model and Thread
Specification. It even has a dedicated code sample page 14 section 3.5 Final Fields that exactly match your question.
To summarize:
A thread that can only see a reference to an object after that object has been completely initialized is guaranteed to see the correctly initialized values for that object’s final fields.
There is no guarantee for non final fields
It means that you have to make sure that an happens-before occurs between your object creation in a thread and its usage in another thread. You can use synchronized, volatile or any other mean to enforce an happens-before.
Since you say in another comment that the field is only set during construction, I would make it... final. Also, such shared objects between threads could suggest some design smell; I would review my design to make sure that I am not creating an overly complex, tightly coupled, hard to debug system.
If the fields are never used outside the class, wrapping their usages with synchronized blocks or inside synchronized functions, two threads won't concurrently modify these fields.
volatile keyword is just a part of thread safety. It only makes the value of a field never be cached, always read from memory. Take this example.
private int myPrivateField = 0;
void someFunction() {
while(myPrivateField ==0) {
}
}
void otherFunction() {
myPrivateField = 1;
}
If someFunction() is called from one thread and it's running for a while,
when you call otherFunction() the value of myPrivateField will not be
"updated" inside someFunction, it was cached to 0 as an otimization.
Making myPrivateField as volatile, the value will always be the one
in memory.
For the example, there won't be much difference for the functions be
synchronized, but without synchronization, you can read a value in an
inconsistent state.
Only final fields are guaranteed to be visible after constructor. Any other field requires some visibility mechanism, such as synchronized or volatile.
This is not as much of a burden as it seems: if the field is not final, then it can be changed by another thread while you're reading it. If teh field can be changed, then the last assigned value must be propagated from the writer thread to the reader thread, whether the writer thread called the constructor or a setter.
If the change in this field is not related to any other field in the class, then the field should be volatile. If the field is related to other fields in the class, then use synchronized or other, more modern locking primitives.
Not answering the entire question, but it should be pointed out that using ThreadLocal is exactly the wrong thing to use if you want to ensure visibility of updated values in all threads. Consider the following code:
class Test {
private static final ThreadLocal<Integer> value = new ThreadLocal<>();
public static void main(String[] args) throws InterruptedException {
System.out.println("From main Thread, value is " + value.get());
value.set(42);
System.out.println("Value has been changed");
Thread t = new Thread() {
public void run() {
System.out.println("From other Thread, value is " + value.get());
}
};
t.start();
t.join();
System.out.println("From main Thread, value is " + value.get());
}
}
This will output the following:
From main Thread, value is null
Value has been changed
From other Thread, value is null
From main Thread, value is 42
i.e. the other thread doesn't see the updated value. This is because changes to the value of a ThreadLocal is, by definition, localized to the thread which changes it.
My personal preference would be to use AtomicReference, since this avoids the risk of forgetting to synchronize externally; it also allows things like atomic compare-and-set, which you don't get with a volatile variable. However, this may not be a requirement for your particular application.
Basically the following works but since I read about the final keyword I am not sure anymore if I have to declare name final if different threads access it?
Thanks in advance.
public class Test4 {
// to ensure thread-safety do we have to declare the variable name final ?
private String name;
public Test4 (String name) {
this.name = name;
}
public void start() {
new MyThread().start();
}
private class MyThread extends Thread {
public void run() {
System.out.println(name);
}
}
public static void main(String[] args) {
Test4 t = new Test4("Don't know if I am threadsafe");
t.start();
}
}
The final modifier - while preventing the member from being re-assigned - does not affect the correctness of the given code1
From the the 17.4.4 Synchronization Order section for the Java 5 Language Specification:
A synchronization order is a total order over all of the synchronization actions of an execution .. Synchronization actions induce the synchronized-with relation on actions, defined as follows:
..
An action that starts a thread synchronizes-with the first action in the thread it starts.
..
Then, since the thread that sets the name member is the one that starts the thread, the synchronization order is guaranteed. (Synchronizes-with implies a Happens-before ordering.)
Note that:
The member name needs only be set before starting the thread: that is, it does not need to be set in the constructor for this synchronizes-with guarantee.
This does not guarantee synchronization ordering - and thus it does not guarantee happens-before or value visibility - between already running threads or threads created elsewhere!
However, final fields do give a much more comfortable feeling (ref. 17.5 Final Field Semantics):
An object is considered to be completely initialized when its constructor finishes. A thread that can only see a reference to an object *after that object has been completely initialized is guaranteed to see the correctly initialized values for that object's final fields.
In this case, with final fields, the value is guaranteed to be visible on every thread after the constructor completes. (This guarantee can be violated by "constructor leaks".)
1 In the supplied code the "non-final" name member is only assigned once before the thread is started.
In different, less trivial, programs other synchronization issues may be exposed. This answer examines if removing final alters the correctness of the supplied code.
All that being said, I consider it "good practice" to use both immutable variables (final) and immutable objects - especially when dealing with threads. Instead of needing to know the little arcane details of the JVM, do the safe proven things and strive for obvious correctness over cleverness or "performance".
See also:
Synchronizing an object shared across threads, but not accessed concurrently
When does java thread cache refresh happens?
Java happend before thread start
final variables are immutable, you can not change the value once it is constructed so it does not have concurrency issue.
You will not get the correct value of the field without final.
Maybe the thread got the old value after you changing the value of field.
Check the Visibility of JMM.
Another link of volatile.
Happends-Before Rule.
Happends-Before in JMM.
Could you be looking for an AtomicReference or perhaps volatile? It depends what you mean by thread safe?
// Atomic to allow deeper control of updates.
private AtomicReference<String> name = new AtomicReference<String>();
// Volatile to ensure it is not cached.
private volatile String vName;
public Test(String name) {
this.name.set(name);
this.vName = name;
}
public void start() {
new MyThread().start();
}
private class MyThread extends Thread {
public void run() {
System.out.println(name.get());
System.out.println(vName);
}
}
final doesn't have nothing with multithreading, but you should put final if your fild shouldn't be changed and is initialized in constructor of class. This means that fild can't be changed latter.
since String is immutable and you declare the field final ,with all threads accessing it after the field assignment, then surely there will be no concurrent issues since the field would be used only for Read operation,in contrast to the case where StringBuilder were used.
The other day Howard Lewis Ship posted a blog entry called "Things I Learned at Hacker Bed and Breakfast", one of the bullet points is:
A Java instance field that is assigned exactly once via lazy
initialization does not have to be synchronized or volatile (as long
as you can accept race conditions across threads to assign to the
field); this is from Rich Hickey
On the face of it this seems at odds with the accepted wisdom about visibility of changes to memory across threads, and if this is covered in the Java Concurrency in Practice book or in the Java language spec then I have missed it. But this was something HLS got from Rich Hickey at an event where Brian Goetz was present, so it would seem there must be something to it. Could someone please explain the logic behind this statement?
This statement sounds a little bit cryptic. However, I guess HLS refers to the case when you lazily initialize an instance field and don't care if several threads performs this initialization more than once.
As an example, I can point to the hashCode() method of String class:
private int hashCode;
public int hashCode() {
int hash = hashCode;
if (hash == 0) {
if (count == 0) {
return 0;
}
final int end = count + offset;
final char[] chars = value;
for (int i = offset; i < end; ++i) {
hash = 31*hash + chars[i];
}
hashCode = hash;
}
return hash;
}
As you can see access to the hashCode field (which holds cached value of the computed String hash) is not synchronized and the field isn't declared as volatile. Any thread which calls hashCode() method will still receive the same value, though hashCode field may be written more than once by different threads.
This technique has limited usability. IMHO it's usable mostly for the cases like in the example: a cached primitive/immutable object which is computed from the others final/immutable fields, but its computation in the constructor is an overkill.
Hrm. As I read this it is technically incorrect but okay in practice with some caveats. Only final fields can safely be initialized once and accessed in multiple threads without synchronization.
Lazy initialized threads can suffer from synchronization issues in a number of ways. For example, you can have constructor race conditions where the reference of the class has been exported without the class itself being initialized fully.
I think it highly depends on whether or not you have a primitive field or an object. Primitive fields that can be initialized multiple times where you don't mind that multiple threads do the initialization would work fine. However HashMap style initialization in this manner may be problematic. Even long values on some architectures may store the different words in multiple operations so may export half of the value although I suspect that a long would never cross a memory page so therefore it would never happen.
I think it depends highly on whether or not an application has any memory barriers -- any synchronized blocks or access to volatile fields. The devil is certainly in the details here and the code that does the lazy initialization may work fine on one architecture with one set of code and not in a different thread model or with an application that synchronizes rarely.
Here's a good piece on final fields as a comparison:
http://www.javamex.com/tutorials/synchronization_final.shtml
As of Java 5, one particular use of the final keyword is a very important and often overlooked weapon in your concurrency armoury. Essentially, final can be used to make sure that when you construct an object, another thread accessing that object doesn't see that object in a partially-constructed state, as could otherwise happen. This is because when used as an attribute on the variables of an object, final has the following important characteristic as part of its definition:
Now, even if the field is marked final, if it is a class, you can modify the fields within the class. This is a different issue and you must still have synchronization for this.
This works fine under some conditions.
its okay to try and set the field more than once.
its okay if individual threads see different values.
Often when you create an object which is not changed e.g. loading a Properties from disk, having more than one copy for a short amount of time is not an issue.
private static Properties prop = null;
public static Properties getProperties() {
if (prop == null) {
prop = new Properties();
try {
prop.load(new FileReader("my.properties"));
} catch (IOException e) {
throw new AssertionError(e);
}
}
return prop;
}
In the short term this is less efficient than using locking, but in the long term it could be more efficient. (Although Properties has a lock of it own, but you get the idea ;)
IMHO, Its not a solution which works in all cases.
Perhaps the point is that you can use more relaxed memory consistency techniques in some cases.
I think the statement is untrue. Another thread can see a partially initialized object, so the reference can be visible to another thread even though the constructor hasn't finished running. This is covered in Java Concurrency in Practice, section 3.5.1:
public class Holder {
private int n;
public Holder (int n ) { this.n = n; }
public void assertSanity() {
if (n != n)
throw new AssertionError("This statement is false.");
}
}
This class isn't thread-safe.
If the visible object is immutable, then I you are OK, because of the semantics of final fields means you won't see them until its constructor has finished running (section 3.5.2).
Is it safe/acceptable practice to lock on a private field variable (instead of using a lock object)? This way, I could have different locks for different purposes. Example below:
class Test {
private Integer x = 0;
private Integer y = 0;
public void incrementX() {
synchronized(x) {
x++;
}
}
public void decrementX() {
synchronized(x) {
x++;
}
}
public void incrementY() {
synchronized(y) {
y++;
}
}
public void decrementY() {
synchronized(y) {
y++;
}
}
Or should I have a lock object for each private member I wish to lock? Example:
class Test {
private final Object xLock = new Object();
private final Object yLock = new Object();
private Integer x = 0;
private Integer y = 0;
...
}
Or should I just have a single general lock and use that for all private variables that require locking? Example:
class Test {
private final Object objLock = new Object();
private Integer x = 0;
private Integer y = 0;
...
}
Beware to always use a final member var for the lock! If you use an Integer, for example, and you plan to change it, that will be very bad practice since each call will see a different object and cause a data race.
Whether you use one or several locks depends on the coordination scheme you want to achieve, so it's entirely domain-specific. You must think through carefully which operations are and which aren't mutually exclusive and assign locks to them appropriately. There is no single best practice here.
If you have two orthogonal operations on your object that may happen simultaneously without causing any datarace, that's a case for two locks. In your example there are two Integers, each changing independently. I see this as a case for two locks. If you had more complex code where in at least one operation you needed to access both Integers, that would tie them together and then you would need a single lock.
It's perfectly acceptable to lock on a private field, as long as this field is an object. Primitives don't have an intrinsic lock, and the first snippet is thus invalid.
I would however avoid locking on a private field if this field is accessible from the outside (using a getter, for example), as this would allow anyone to lock on the same object for different purposes. The second solution is thus the cleanest, IMHO.
Using a single lock is counter-productive, since it prevents concurrent access to methods which should be able to run concurrently. It's thus generally better to have fine-grained the locks.
EDIT:
now that you have changed your question and use wrapper objects, the locking on the private Integer instances is really not a good solution, as you change the values of these variables inside the methods. Use final fields as locks.
Remember that x++, if x is an Integer instance, is equivalent to:
int temp = x.intValue();
temp++;
x = Integer.valueOf(temp);
Moreover, since Integer.valueOf() caches Integer instances, you might have several classes using the same Integer instance to lock completely different things. A recipe for slow execution and deadlocks.
I think you should have two different lock for the two fields. You lock the object to prevent two or more thread access the same object at the same time.
You can also take a look to the Lock object in java http://docs.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/locks/Lock.html
It is more performant than the synchronize, and in the java.util.concurrent there are some utility class to work with locks (also a ReadWriteLock, if you need it)
AFAIK the lock object you use is only as an ID. I mean, you can use whatever object you want. The only important thing is "if two things must be mutually exclusive, then they must use the same lock".
So the approach of using the very own var seems ok.
BUT, remember!!
I don't think you can lock on a primitive, it must be an Object
If you change the field value, next process will acquire a different lock!!!
So the separate lock seems safer. Except you are absolutely sure your field is not going to change (in fact, you should declare it as final).