As I am trying to get to grips with thread safety, I would like to know if this class is threadsafe? If two threads try to access its variables at any time it seems to me that it is thread safe because:
final variable is threadsafe by virtue of being immutable.
getter and setter are synchronized, so mObject can only be gotten, or set by one thread at a time. So there is no chance of two threads reading different values.
The method changeObj() is not synchronized but any block in it which deals with class variables (i.e. mObject) is synchronized.
Please tell me if I am wrong or if this class is not threadsafe.
public class MyClass{
private final String = "mystring"; //thread safe because final
private AnObject mObject;
public MyClass(){
//initialize
}
//only one class can set the object at a time.
public synchronized void setObj(AnObject a){
mObject = a;
}
//two threads trying to get the same object will not read different values.
public synchronized AnObject getObj(){
return mObject;
}
//better to synchronize the smallest possible block than the whole method, for performance.
public void changeObj(){
//just using local variables (on stack) so no need to worry about thread safety
int i = 1;
//i and j are just to simulate some local variable manipulations.
int j =3;
j+=i;
synchronized(this){
//change values is NOT synchronized. Does this matter? I don't think so.
mObject.changeValues();
}
}
}
No, it's not thread safe. You make sure only one thread can change the values in your AnObject at a time if it uses the changeObj() method, but you also provide a getter for this object, so any other thread could call changeValues() concurrently.
Your class in itself is thread safe in its current state (assuming any methods not shown here are), however you have one likely "bug" in your thinking;
mObject isn't 100% encapsulated, it is passed in through a setter and can be fetched through a getter. That means that any thread could get a reference to and call methods on the object referenced by mObject simultaneously without MyClass knowing about it.
In other words, AnObject's methods may need to be thread safe too.
At the very least, the synchronizing in MyClass doesn't in any way make mObject safe from threading problems.
Adding to Mr. JB Nizet's points, if AnObject.changeValues is a method that is designed to be overridden by clients, or calls such methods, then this, in the general case, opens the door for various unwanted behaviours, like deadlocks and data corruption. You must never cede control to alien code within a synchronized block. By "alien" I mean code not under your control. More details can be found in Effective Java, 2nd Ed, Item 67.
A final variable is not necessarily thread safe, only immutable final variables are thread safe -- that covers primitives and classes like String, or final variables of classes which themselves are thread-safe.
Your class is not thread safe because it exposes the variable a, but also requires it for its internal working.
The below example will demonstrate an example of how a could get into an inconsistent state.
Thread A
MyClass myClass = ...
myClass.changeObj();
// imagine Thread A is suspended during the synchronized block inside of
// changeObj()
Thead B
MyClass myClass = ...
AnObj anObj = myClass.getObj();
anObj.changeValues();
// uh-oh, I am modifying the state of this instance of anObj which is also
// currently being modified by Thread A
For MyClass to be truly thread safe you must do one of the following.
AnObj must also guarantee thread safety (by making methods that modify its state thread-safe)
AnObj must be immutable. That is, if you need to modify the state of AnObj you must create new instance of AnObj to hold the new state.
The getter for AnObj must not directly expose MyClass's instance of AnObj, but a rather return a copy of that instance.
Related
public class Test{
private MyObj myobj = new MyObj(); //it is not volatile
public class Updater extends Thred{
myobje = getNewObjFromDb() ; //not am setting new object
}
public MyObj getData(){
//getting stale date is fine for
return myobj;
}
}
Updated regularly updates myobj
Other classes fetch data using getData
IS this code thread safe without using volatile keyword?
I think yes. Can someone confirm?
No, this is not thread safe. (What makes you think it is?)
If you are updating a variable in one thread and reading it from another, you must establish a happens-before relationship between the write and the subsequent read.
In short, this basically means making both the read and write synchronized (on the same monitor), or making the reference volatile.
Without that, there are no guarantees that the reading thread will see the update - and it wouldn't even be as simple as "well, it would either see the old value or the new value". Your reader threads could see some very odd behaviour with the data corruption that would ensue. Look at how lack of synchronization can cause infinite loops, for example (the comments to that article, especially Brian Goetz', are well worth reading):
The moral of the story: whenever mutable data is shared across threads, if you don’t use synchronization properly (which means using a common lock to guard every access to the shared variables, read or write), your program is broken, and broken in ways you probably can’t even enumerate.
No, it isn't.
Without volatile, calling getData() from a different thread may return a stale cached value.
volatile forces assignments from one thread to be visible on all other threads immediately.
Note that if the object itself is not immutable, you are likely to have other problems.
You may get a stale reference. You may not get an invalid reference.
The reference you get is the value of the reference to an object that the variable points to or pointed to or will point to.
Note that there are no guarantees how much stale the reference may be, but it's still a reference to some object and that object still exists. In other words, writing a reference is atomic (nothing can happen during the write) but not synchronized (it is subject to instruction reordering, thread-local cache et al.).
If you declare the reference as volatile, you create a synchronization point around the variable. Simply speaking, that means that all cache of the accessing thread is flushed (writes are written and reads are forgotten).
The only types that don't get atomic reads/writes are long and double because they are larger than 32-bits on 32-bit machines.
If MyObj is immutable (all fields are final), you don't need volatile.
The big problem with this sort of code is the lazy initialization. Without volatile or synchronized keywords, you could assign a new value to myobj that had not been fully initialized. The Java memory model allows for part of an object construction to be executed after the object constructor has returned. This re-ordering of memory operations is why the memory-barrier is so critical in multi-threaded situations.
Without a memory-barrier limitation, there is no happens-before guarantee so you do not know if the MyObj has been fully constructed. This means that another thread could be using a partially initialized object with unexpected results.
Here are some more details around constructor synchronization:
Constructor synchronization in Java
Volatile would work for boolean variables but not for references. Myobj seems to perform like a cached object it could work with an AtomicReference. Since your code extracts the value from the DB I'll let the code stay as is and add the AtomicReference to it.
import java.util.concurrent.atomic.AtomicReference;
public class AtomicReferenceTest {
private AtomicReference<MyObj> myobj = new AtomicReference<MyObj>();
public class Updater extends Thread {
public void run() {
MyObj newMyobj = getNewObjFromDb();
updateMyObj(newMyobj);
}
public void updateMyObj(MyObj newMyobj) {
myobj.compareAndSet(myobj.get(), newMyobj);
}
}
public MyObj getData() {
return myobj.get();
}
}
class MyObj {
}
I have several threads trying to increment a counter for a certain key in a not thread-safe custom data structure (which you can image to be similiar to a HashMap). I was wondering what the right way to increment the counter in this case would be.
Is it sufficient to synchronize the increment function or do I also need to synchronize the get operation?
public class Example {
private MyDataStructure<Key, Integer> datastructure = new CustomDataStructure<Key, Integer>();
private class MyThread implements Runnable() {
private synchronized void incrementCnt(Key key) {
// from the datastructure documentation: if a value already exists for the given key, the
// previous value will be replaced by this value
datastructure.put(key, getCnt(key)+1);
// or can I do it without using the getCnt() function? like this:
datastructure.put(key, datastructure.get(key)+1));
}
private synchronized int getCnt(Key key) {
return datastructure.get(key);
}
// run method...
}
}
If I have two threads t1, t2 for example, I would to something like:
t1.incrementCnt();
t2.incrmentCnt();
Can this lead to any kind of deadlock? Is there a better way to solve this?
Main issue with this code is that it's likely to fail in providing synchronization access to datastructure, since accessing code synchronizing on this of an inner class. Which is different for different instances of MyThread, so no mutual exclusion will happen.
More correct way is to make datastructure a final field, and then to synchronize on it:
private final MyDataStructure<Key, Integer> datastructure = new CustomDataStructure<Key, Integer>();
private class MyThread implements Runnable() {
private void incrementCnt(Key key) {
synchronized (datastructure) {
// or can I do it without using the getCnt() function? like this:
datastructure.put(key, datastructure.get(key)+1));
}
}
As long as all data access is done using synchronized (datastructure), code is thread-safe and it's safe to just use datastructure.get(...). There should be no dead-locks, since deadlocks can occur only when there's more than one lock to compete for.
As the other answer told you, you should synchronize on your data structure, rather than on the thread/runnable object. It is a common mistake to try to use synchronized methods in the thread or runnable object. Synchronization locks are instance-based, not class-based (unless the method is static), and when you are running multiple threads, this means that there are actually multiple thread instances.
It's less clear-cut about Runnables: you could be using a single instance of your Runnable class with several threads. So in principle you could synchronize on it. But I still think it's bad form because in the future you may want to create more than one instance of it, and get a really nasty bug.
So the general best practice is to synchronize on the actual item that you are accessing.
Furthermore, the design conundrum of whether or not to use two methods should be solved by moving the whole thing into the data structure itself, if you can do so (if the class source is under your control). This is an operation that is confined to the data structure and applies only to it, and doing the increment outside of it is not good encapsulation. If your data structure exposes a synchronized incrementCnt method, then:
It synchronizes on itself, which is what you wanted.
It can use its own private fields directly, which means you don't actually need to call a getter and a setter.
It is free to have the implementation changed to one of the atomic structures in the future if it becomes possible, or add other implementation details (such as logging increment operations separately from setter access operations).
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.
Let's say I have a JavaBean User that's updated from another thread like this:
public class A {
private final User user;
public A(User user) {
this.user = user;
}
public void aMethod() {
Thread thread = new Thread(new Runnable() {
#Override
public void run() {
...a long running task..
user.setSomething(something);
}
});
t.start();
t.join();
}
public void anotherMethod() {
GUIHandler.showOnGuiSomehow(user);
}
}
Is this code thread safe? I mean, when the thread that created A instance and called A.aMethod reads user fields, does it see user in the fresh state? How to do it in appropriate thread safe manner?
Note that I can't modify the user class and I don't know if it's thread safe itself.
Is this code thread safe? ... does it see user in the fresh state?
Not especially - the fact that user is final in your code makes almost no difference to thread safety other than the fact that it cannot be replaced.
The bit that should change is the instance variable that is set by setSomething. It should be marked as volatile.
class User {
// Marked `volatile` to ensure all writes are visible to other threads.
volatile String something;
public void setSomething(String something) {
this.something = something;
}
}
If however (as you suggest) you do not have access to the User class, you must then perform a synchronization that creates a memory barrier. In its simplest form you could surround your access to the user with a synchronized access.
synchronized (user) {
user.setSomething(something);
}
Added :- It turns out (see here) that this can actually be done like this:
volatile int barrier = 0;
...
user.setSomething(something);
// Forces **all** cached variable to be flushed.
barrier += 1;
marking field as final just means that reference cannot be changed. It means nothing about thread safity of class User. If methods of this class that access fields are synchronized (or use other synchronization technique) it is thread safe. Otherwise it is not.
final only makes the reference not re-assignable, but if the reference points to a mutable class, you can still alter the state inside that object, which causes thead-unsafe.
Your code is only thread safe if the User class is immutable, I.e. all properties of User cannot be altered outside the object, all references in the class point to other immutable class.
If it is not case, then you have to properly synchronize its methods to make it thread safe.
Note that I can't modify the user class and I don't know if it's thread safe itself.
You have to synchronize your access when accessing the User object.
You can for example use the User object to synchronize, so just wrap every access on the user object with something like:
synchronized(user) {
// access some method of the user object
}
That assumes that the user object is only accessed in your threads asynchronously. Also keep the synchronized blocks short.
You could also build a threadsafe wrapper around the user object. I would suggest that if you have a lot of different calls, the code gets cleaner and better to read that way.
good luck!
Concerning threading, finalfields are just guaranteed to be consistent in case of constructor escape, since the JSR-133 about Memory Barrier mechanism:
The values for an object's final fields are set in its constructor.
Assuming the object is constructed "correctly", once an object is
constructed, the values assigned to the final fields in the
constructor will be visible to all other threads without
synchronization. In addition, the visible values for any other object
or array referenced by those final fields will be at least as
up-to-date as the final fields. What does it mean for an object to be
properly constructed? It simply means that no reference to the object
being constructed is allowed to "escape" during construction. (See
Safe Construction Techniques for examples.) In other words, do not
place a reference to the object being constructed anywhere where
another thread might be able to see it; do not assign it to a static
field, do not register it as a listener with any other object, and so
on. These tasks should be done after the constructor completes, not in
the constructor.
However, nothing ensures automatic thread-safety about any final fields in the remaining object's life (meaning after wrapping class's constructor execution).. Indeed, immutability in Java is a pure misnomer:
Now, in common parlance, immutability means "does not change".
Immutability doesn't mean "does not change" in Java. It means "is
transitively reachable from a final field, has not changed since the
final field was set, and a reference to the object containing the
final field did not escape the constructor".
Yes, this is safe. See
Java Language Specification (Java 8) Chapter 17.4.4:
The final action in a thread T1 synchronizes-with any action in another thread T2 that detects that T1 has terminated.
T2 may accomplish this by calling T1.isAlive() or T1.join().
Put this together with 17.4.5. Happens-before Order:
Two actions can be ordered by a happens-before relationship. If one action happens-before another, then the first is visible to and ordered before the second. [..] If an action x synchronizes-with a following action y, then we also have hb(x, y).
So after you call t.join(); in your code you will see the updated changes. Since "the thread that created A instance and called A.aMethod" can impossibly read the value after calling aMethod and before t.join is called (because it is busy with method aMethod), this is safe.
If I have a class, call it X and X contains a collection (assume I am not using one of the synchronized colections, just a normal one).
If I was to write my own method synchronized add()- how does the locking work? Is the locking done on the instance of X, and not on the collection object?
So synchronizing my add() method would not stop many instances of X from calling add() and inserting into the collection- therefore I could still have threading problems?
A synchronized method locks the object. If your X.add is synchronized, it will prevent concurrent execution of other synchronized methods of the same X object. If anyone out of that X object has access to the same collection, the collection will not be protected.
If you want your collection to be protected, make sure it is not accessible to the rest of the world in any way other than a synchronized method of X. Also, this is a bit unclear in your question, but note that a synchronized non-static method locks the object. Assuming each X instance will have a collection of its own, they won't interfere with each other.
Another option, BTW, is to lock the collection instead of the X object:
void add(Object o) {
synchronized(myCollection) {
myCollection.add(o);
}
}
This will synchronize access to the locked collection instead of the X object. Use whichever you find easier and more effective.
In your example, synchronized will make sure only one thread can invoke the method on one instance of the class at a time. Other methods could access that collection, which would not be safe. Look up concurrent collections for more information on thread-safe collection implementations.
If I was to write my own method synchronized add()- how does the locking work? Is the locking done on the instance of X, and not on the collection object?
The locking is done on the object that you synchronized on -- not any fields within the object. For locking to work, all of the threads must synchronize on the same exact object. Typically a private final object is best to be locked on.
private final Collection<...> myCollection = ...
...
synchronize (myCollection) {
myCollection.add(...);
}
Although a common pattern is to lock on the object that you are protecting, it really can be any constant object. You could also do:
private final Object lockObject = new Object();
...
synchronize (lockObject) {
myCollection.add(...);
}
So synchronizing my add() method would not stop many instances of X from calling add() and inserting into the collection- therefore I could still have threading problems?
If other parts of your application are accessing the myCollection without being inside of a synchronized (myCollection) block, then yes, you are going to have threading problems. You would need to synchronize around all accesses to properly protect the collection and provide a memory barrier. That means add(...), contains(...), iterators, etc..
Often, if you are trying to protect a collection or other class, it makes sense to wrap it in a class which does the synchronization. This hides the locking and protects the collection from unintended modifications from code that is missing a synchronized block.
Is it true that you are sharing one collection across many X instances? Then you need to synchronize on the collection instance itself. Don't make the method itself synchronized, but wrap all its code in a synchronized(coll) { ... } block.
If, on the other hand, each X has its own collection, then synchronized add() is all you need. This will guarantee that no two threads are executing add on the same instance at the same time.