I'm wondering if the following class is thread safe:
class Example {
private Thing thing;
public setThing(Thing thing) {
this.thing = thing;
}
public use() {
thing.function();
}
}
Specifically, what happens if one thread calls setThing while another thread is in Thing::function via Example::use?
For example:
Example example = new Example();
example.setThing(new Thing());
createThread(example); // create first thread
createThread(example); // create second thread
//Thread1
while(1) {
example.use();
}
//Thread2
while(1) {
sleep(3600000); //yes, i know to use a scheduled thread executor
setThing(new Thing());
}
Specifically, I want to know, when setThing is called while use() is executing, will it continue with the old object successfully, or could updating the reference to the object somehow cause a problem.
There are 2 points when reasoning about thread safety of a particulcar class :
Visibility of shared state between threads.
Safety (preserving class invariants) when class object is used by multiple threads through class methods.
Shared state of Example class consists only from one Thing object.
The class isn't thread safe from visibility perspective. Result of setThing by one thread isn't seen by other threads so they can work with stale data. NPE is also acceptable cause initial value of thing during class initialization is null.
It's not possible to say whether it's safe to access Thing class through use method without its source code. However Example invokes use method without any synchronization so it should be, otherwise Example isn't thread safe.
As a result Example isn't thread safe. To fix point 1 you can either add volatile to thing field if you really need setter or mark it as final and initialize in constructor. The easiest way to ensure that 2 is met is to mark use as synchronized. If you mark setThing with synchronized as well you don't need volatile anymore. However there lots of other sophisticated techniques to meet point 2. This great book describes everything written here in more detail.
If the method is sharing resources and the thread is not synchronized, then the they will collide and several scenarios can occur including overwriting data computed by another thread and stored in a shared variable.
If the method has only local variables, then you can use the method by mutliple threads without worring about racing. However, usually non-helper classes manipulate member variables in their methods, therefore it's recommended to make methods synchronized or if you know exactly where the problem might occur, then lock (also called synchronize) a subscope of a method with a final lock/object.
Related
So I'm pretty good overall when it comes to the thread-safety of code, but I'm currently encountering a situation where I'm not clear on the best way to handle it.
I have an instance variable, non-final because the enclosing class can change its value. This variable is an object that has several methods that get called on it during the application. Here is a quick sample to show what I mean.
private class Foo{
private FooFoo fooFoo;
public synchronized void setFooFoo(FooFoo fooFoo){
this.fooFoo = fooFoo;
}
public void doSomething(){
fooFoo.doSomething(); //How do I make this line thread-safe?
}
}
Changing the reference of the fooFoo field is easy, just simple synchronization. But what about when the doSomething() method is called on fooFoo? I'm always hesitant to synchronize on an alien method due to deadlock risk.
In the real cases this is based on, there are many different variations of this. My company's application is a sprawling code base that frequently resembles a bowl of spaghetti, so when it comes to writing any kind of synchronized code I'm extra paranoid, because of the tight coupling and the fact that there are developers not only here in the US, but in an offshore firm in eastern europe working on it and I do not trust all of them to make good coding decisions.
So I'm just looking for the best practice to handle this kind of situation in a multi-threaded environment. Thanks.
fooFoo.doSomething(); //How do I make this line thread-safe?
Hint: You can't make that one line thread-safe unless that is the only line in the whole program that ever accesses the object.
Thread-safety is not about making particular lines of code or particular methods thread safe: It's about making data thread safe.
Does fooFoo refer to a mutable object? If not, then that line already is thread safe. But if the object is mutable, then thread-safety, at a minimum, means insuring that unintended interactions between two or more threads can not put that object into an invalid state; and at the worst case it means insuring the consistency of relationships between the fooFoo object and other objects in your program.
Any time there is an important relationship between two or more pieces of data that are shared between threads, then you probably need to throw a synchronized block around any bit of code that could temporarily violate that relationship, and you need to throw a synchronized block around any bit of code that depends on that relationship---even if the code only looks at the data.
In your case you would have to make doSomething() synchronized too, because you need to lock every time a concurrent access on a mutable part of the class occurs. While you are only reading fooFoo in doSomething, you could at the same time be writing fooFoo in setFooFoo(), thus creating a data race. synchronized essentially causes the function call to take a lock that is associated with the Java-object at entry and to release it once you leave the function.
Alternatively you can use a Lock member inside Foo that you take when you do either. This applies in situations, where you may have multiple independent members that may be accessed safely while the other is being altered. In this case taking two different locks may make your code substantially faster.
For completeness sake it should be mentioned that in some older Java versions (Java 5 only I believe) taking the intrinsic lock of the object through a synchronized method, was substantially slower than using a lock object.
For the deadlock problem: you are right to worry about this, but consider it as a separate issue, after you make your object thread-safe in the first place. The question there is what other locks are taken and it is not possible to answer this with just what you posted. Given your object, synchronizing the read/write on the object can not deadlock by itself, because only one operation can be active at the time, and they do not take any other locks from what you show in your code.
It depends upon what your concerns are for thread safety.
If foo is only delegated to you can simply make it volatile. This will prevent threads from cashing a reference to the old value if the reference is updated. FooFoo can then handle it's own thread safety concerns.
private class Foo{
private volatile FooFoo fooFoo;
public void setFooFoo(FooFoo fooFoo){
this.fooFoo = fooFoo;
}
public void doSomething(){
fooFoo.doSomething();
}
}
If your concern is about thread safety of Foo itself, and it is doing more then just delegating calls you should synchronize relevant methods.
private class Foo{
private FooFoo fooFoo;
public synchronized void setFooFoo(FooFoo fooFoo){
this.fooFoo = fooFoo;
}
public synchronized void doSomething(){
fooFoo.doSomething();
}
public synchronized void doSomethingElse() {
int values = fooFoo.getValue();
// do some things
fooFoo.setValue(values + somethingElse);
}
}
Read and write operations to reference variables and primitive variables are atomic in java.
Say I have the following class:
public class Example{
private int k;
public void setK(int k){
this.k = k;
}
}
As far as I understand it is a thread safe because integer assignment is atomic. But what about visibility? When one thread update k does it means other thead will see the updated value?
Thank u in advace
It is neither thread-safe nor establishes a visibility from one thread to another. It is not thread-safe because this.k = k; is a read and write operation. In order to establish the latter, you can have the variable declared volatile. In this case, you can also use AtomicInteger.
As far as I understand it is a thread safe because...
If you've shown us the whole Example class then it is absolutely thread-safe. Your class is thread safe because it has no publicly visible state.
A class is "thread safe" if there is no way for overlapped method calls from multiple threads to put the class or any of its instances into a bad state. Your Example class can't get into a bad state because it does not publish any state whatsoever: The class has only one method, e.setK(int), but that method has no effect on anything that client code can see.
If, on the other hand, you have only shown us part of the Example class, then there is no way that anybody can say whether the class is thread-safe or not. We'd have to see the rest of the class. Are there other fields besides k? What is the relationship between them? Are there methods whose behavior depend on the value of k? What promises does your class's API contract make about how an instance will behave for different values of k?
Without that information, we can not even begin to talk about thread safety.
I have a Util class with a utility methods as:
public static String formatAmount(String amount) throws Exception {
return String.format("%,.2f", Double.valueOf(amount));
}
Is this method thread safe? I am not modifying amount any where else.
Secondly, I have another method as.
private boolean checkIfDateIsAHoliday(org.joda.time.LocalDate date) {
boolean isHoliday = false;
.......
return isHoliday;
}
Is this method thread safe? I am not modifying date any where else.
As always the hell is in the small details. Your first method is thread safe because it definitely does not change state of any class.
Your seconds method is available only partially. I do not know what is written in your code instead of ........ If you do not change state your any class there the method is thread-safe, otherwise it is not.
Thread safety is all about accessing shared state. So if you want to know if a method is thread safe, you only have to check if it accesses state (=fields) that can also be accessed by other threads:
If there is no such state, you're done - the method is thread safe.
If there is such state, you have to check if it is accessed in a thread safe manner.
(See also http://tutorials.jenkov.com/java-concurrency/thread-safety.html)
Your first method does not access any shared state (String is immutable, hence the parameter is thread-safe by itself). It calls two static methods (String.format and Double.valueOf) which might access shared state. Unfortunately, javadoc does not say anything concerning thread-safety of these two methods. Nevertheless we can assume that they are (otherwise almost all java applications were broken).
Your second method is thread safe concerning the code we can see (we can't argue about the code behind .....). Reason: You're just modifying local state (stack variable isHoliday). As local state cannot be accessed by other threads, this is thread-safe by definition.
Now just try to argue concerning the rest of your code (.....)!
For the First method it will be Thread safe But
It won't be Thread Safe for the method you have declared in the second
The first one is thread-safe because you are only reading an immutable variable String.
Joda's LocalDate is also immutable. Therefore, assuming you are not reading or writing mutable class or instance fields, this method is also threadsafe.
Consider the following class:
public class MyClass
{
private MyObject obj;
public MyClass()
{
obj = new MyObject();
}
public void methodCalledByOtherThreads()
{
obj.doStuff();
}
}
Since obj was created on one thread and accessed from another, could obj be null when methodCalledByOtherThread is called? If so, would declaring obj as volatile be the best way to fix this issue? Would declaring obj as final make any difference?
Edit:
For clarity, I think my main question is:
Can other threads see that obj has been initialized by some main thread or could obj be stale (null)?
For the methodCalledByOtherThreads to be called by another thread and cause problems, that thread would have to get a reference to a MyClass object whose obj field is not initialized, ie. where the constructor has not yet returned.
This would be possible if you leaked the this reference from the constructor. For example
public MyClass()
{
SomeClass.leak(this);
obj = new MyObject();
}
If the SomeClass.leak() method starts a separate thread that calls methodCalledByOtherThreads() on the this reference, then you would have problems, but this is true regardless of the volatile.
Since you don't have what I'm describing above, your code is fine.
It depends on whether the reference is published "unsafely". A reference is "published" by being written to a shared variable; another thread reads the variable to get the reference. If there is no relationship of happens-before(write, read), the publication is called unsafe. An example of unsafe publication is through a non-volatile static field.
#chrylis 's interpretation of "unsafe publication" is not accurate. Leaking this before constructor exit is orthogonal to the concept of unsafe publication.
Through unsafe publication, another thread may observe the object in an uncertain state (hence the name); in your case, field obj may appear to be null to another thread. Unless, obj is final, then it cannot appear to be null even if the host object is published unsafely.
This is all too technical and it requires further readings to understand. The good news is, you don't need to master "unsafe publication", because it is a discouraged practice anyway. The best practice is simply: never do unsafe publication; i.e. never do data race; i.e. always read/write shared data through proper synchronization, by using synchronized, volatile or java.util.concurrent.
If we always avoid unsafe publication, do we still need final fields? The answer is no. Then why are some objects (e.g. String) designed to be "thread safe immutable" by using final fields? Because it's assumed that they can be used in malicious code that tries to create uncertain state through deliberate unsafe publication. I think this is an overblown concern. It doesn't make much sense in server environments - if an application embeds malicious code, the server is compromised, period. It probably makes a bit of sense in Applet environment where JVM runs untrusted codes from unknown sources - even then, this is an improbable attack vector; there's no precedence of this kind of attack; there are a lot of other more easily exploitable security holes, apparently.
This code is fine because the reference to the instance of MyClass can't be visible to any other threads before the constructor returns.
Specifically, the happens-before relation requires that the visible effects of actions occur in the same order as they're listed in the program code, so that in the thread where the MyClass is constructed, obj must be definitely assigned before the constructor returns, and the instantiating thread goes directly from the state of not having a reference to the MyClass object to having a reference to a fully-constructed MyClass object.
That thread can then pass a reference to that object to another thread, but all of the construction will have transitively happened-before the second thread can call any methods on it. This might happen through the constructing thread's launching the second thread, a synchronized method, a volatile field, or the other concurrency mechanisms, but all of them will ensure that all of the actions that took place in the instantiating thread are finished before the memory barrier is passed.
Note that if a reference to this gets passed out of the class inside the constructor somewhere, that reference might go floating around and get used before the constructor is finished. That's what's known as unsafe publishing of the object, but code such as yours that doesn't call non-final methods from the constructor (or directly pass out references to this) is fine.
Your other thread could see a null object. A volatile object could possibly help, but an explicit lock mechanism (or a Builder) would likely be a better solution.
Have a look at Java Concurrency in Practice - Sample 14.12
This class (if taken as is) is NOT thread safe. In two words: there is reordering of instructions in java (Instruction reordering & happens-before relationship in java) and when in your code you're instantiating MyClass, under some circumstances you may get following set of instructions:
Allocate memory for new instance of MyClass;
Return link to this block of memory;
Link to this not fully initialized MyClass is available for other threads, they can call "methodCalledByOtherThreads()" and get NullPointerException;
Initialize internals of MyClass.
In order to prevent this and make your MyClass really thread safe - you either have to add "final" or "volatile" to the "obj" field. In this case Java's memory model (starting from Java 5 on) will guarantee that during initialization of MyClass, reference to alocated for it block of memory will be returned only when all internals are initialized.
For more details I would strictly recommend you to read nice book "Java Concurrency in Practice". Exactly your case is described on the pages 50-51 (section 3.5.1). I would even say - you just can write correct multithreaded code without reading that book! :)
The originally picked answer by #Sotirios Delimanolis is wrong. #ZhongYu 's answer is correct.
There is the visibility issue of the concern here. So if MyClass is published unsafely, anything could happen.
Someone in the comment asked for evidence - one can check Listing 3.15 in the book Java Concurrency in Practice:
public class Holder {
private int n;
// Initialize in thread A
public Holder(int n) { this.n = n; }
// Called in thread B
public void assertSanity() {
if (n != n) throw new AssertionError("This statement is false.");
}
}
Someone comes up an example to verify this piece of code:
coding a proof for potential concurrency issue
As to the specific example of this post:
public class MyClass{
private MyObject obj;
// Initialize in thread A
public MyClass(){
obj = new MyObject();
}
// Called in thread B
public void methodCalledByOtherThreads(){
obj.doStuff();
}
}
If MyClass is initialized in Thread A, there is no guarantee that thread B will see this initialization (because the change might stay in the cache of the CPU that Thread A runs on and has not propagated into main memory).
Just as #ZhongYu has pointed out, because the write and read happens at 2 independent threads, so there is no happens-before(write, read) relation.
To fix this, as the original author has mentioned, we can declare private MyObject obj as volatile, which will ensure that the reference itself will be visible to other threads in timely manner
(https://www.logicbig.com/tutorials/core-java-tutorial/java-multi-threading/volatile-ref-object.html) .
I'm trying to learn about singleton classes and how they can be used in an application to keep it thread safe. Let's suppose you have an singleton class called IndexUpdater whose reference is obtained as follows:
public static synchronized IndexUpdater getIndexUpdater() {
if (ref == null)
// it's ok, we can call this constructor
ref = new IndexUpdater();
return ref;
}
private static IndexUpdater ref;
Let's suppose there are other methods in the class that do the actual work (update indicies, etc.). What I'm trying to understand is how accessing and using the singleton would work with two threads. Let's suppose in time 1, thread 1 gets a reference to the class, through a call like this IndexUpdater iu = IndexUpdater.getIndexUpdater(); Then,
in time 2, using reference iu, a method within the class is called iu.updateIndex by thread 1. What would happen in time 2, a second thread tries to get a reference to the class. Could it do this and also access methods within the singleton or would it be prevented as long as the first thread has an active reference to the class. I'm assuming the latter (or else how would this work?) but I'd like to make sure before I implement.
Thank you,
Elliott
Since getIndexUpdater() is a synchronized method, it only prevents threads from accessing this method (or any method protected by the same synchronizer) simultaneously. So it could be a problem if other threads are accessing the object's methods at the same time. Just keep in mind that if a thread is running a synchronized method, all other threads trying to run any synchronized methods on the same object are blocked.
More info on:
http://download.oracle.com/javase/tutorial/essential/concurrency/syncmeth.html
Your assumption is wrong. Synchronizing getIndexUpdater() only prevents more than one instance being created by different threads calling getIndexUpdater() at (almost) the same time.
Without synchronization the following could happen: Thread one calls getIndexUpdater(). ref is null. Thread 2 calls getIndexUpdater(). ref is still null. Outcome: ref is instantiated twice.
You are conflating the instantiation of a singleton object with its use. Synchronizing the creation of a singleton object does not guarantee that the singleton class itself is thread-safe. Here is a simple example:
public class UnsafeSingleton {
private static UnsafeSingleton singletonRef;
private Queue<Object> objects = new LinkedList<Object>();
public static synchronized UnsafeSingleton getInstance() {
if (singletonRef == null) {
singletonRef = new UnsafeSingleton();
}
return singletonRef;
}
public void put(Object o) {
objects.add(o);
}
public Object get() {
return objects.remove(o);
}
}
Two threads calling getInstance are guaranteed to get the same instance of UnsafeSingleton because synchronizing this method guarantees that singletonRef will only be set once. However, the instance that is returned is not thread safe, because (in this example) LinkedList is not a thread-safe queue. Two threads modifying this queue may result in unexpected behavior. Additional steps have to be taken to ensure that the singleton itself is thread-safe, not just its instantiation. (In this example, the queue implementation could be replaced with a LinkedBlockingQueue, for example, or the get and put methods could be marked synchronized.)
Then, in time 2, using reference iu, a method within the class is called iu.updateIndex by thread 1. What would happen in time 2, a second thread tries to get a reference to the class. Could it do this and also access methods within the singleton ...?
The answer is yes. Your assumption on how references are obtained is wrong. The second thread can obtain a reference to the Singleton. The Singleton pattern is most commonly used as a sort of pseudo-global state. As we all know, global state is generally very difficult to deal with when multiple entities are using it. In order to make your singleton thread safe you will need to use appropriate safety mechanisms such as using atomic wrapper classes like AtomicInteger or AtomicReference (etc...) or using synchronize (or Lock) to protect critical areas of code from being accessed simultaneously.
The safest is to use the enum-singleton.
public enum Singleton {
INSTANCE;
public String method1() {
...
}
public int method2() {
...
}
}
Thread-safe, serializable, lazy-loaded, etc. Only advantages !
When a second thread tries to invoke getIndexUpdater() method, it will try to obtain a so called lock, created for you when you used synchronized keyword. But since some other thread is already inside the method, it obtained the lock earlier and others (like the second thread) must wait for it.
When the first thread will finish its work, it will release the lock and the second thread will immediately take it and enter the method. To sum up, using synchronized always allows only one thread to enter guarded block - very restrictive access.
The static synchronized guarantees that only one thread can be in this method at once and any other thread attempting to access this method (or any other static synchronized method in this class) will have to wait for it to complete.
IMHO the simplest way to implement a singleton is to have a enum with one value
enum Singleton {
INSTANCE
}
This is thread safe and only creates the INSTANCE when the class is accessed.
As soon as your synchronized getter method will return the IndexUpdater instance (whether it was just created or already existed doesn't matter), it is free to be called from another thread. You should make sure your IndexUpdater is thread safe so it can be called from multiple threads at a time, or you should create an instance per thread so they won't be shared.