thread safety on single instance method in java - java

If I have one instance of an object A and it has an instance method foo() with only variables created and used in that method is that method thread safe even if the same instance is accessed by many threads?
If yes, does this still apply if instance method bar() on object A creates many threads and calls method foo() in the text described above?
Does it mean that every thread gets a "copy" of the method even if it belongs to the same instance?
I have deliberately not used the synchronized keyword.
Thanks

Yes. All local variables (variables defined within a method) will be on their own Stack frame. So, they will be thread safe, provided a reference is not escaping the scope (method)
Note : If a local reference escapes the method (as an argument to another method) or a method works on some class level or instance level fields, then it is not thread-safe.
Does it mean that every thread gets a "copy" of the method even if it belongs to the same instance
No, there will be only one method. every thread shares the same method. But each Thread will have its own Stack Frame and local variables will be on that thread's Stack frame. Even if you use synchronize on local Objects, Escape Analysis proves that the JVM will optimize your code and remove all kinds of synchronization.
example :
public static void main(String[] args) {
Object lock = new Object();
synchronized (lock) {
System.out.println("hello");
}
}
will be effectively converted to :
public static void main(String[] args) {
Object lock = new Object(); // JVm might as well remove this line as unused Object or instantiate this on the stack
System.out.println("hello");
}

You have to separate the code being run, and the data being worked on.
The method is code, executed by each of the threads. If that code contains a statement such as int i=5 which defines a new variable i, and sets its value to 5, then each thread will create that variable.
The problem with multi-threading is not with common code, but with common data (and other common resources). If the common code accesses some variable j that was created elsewhere, then all threads will access the same variable j, i.e. the same data. If one of these threads modifies the shared data while the others are reading, all kinds of errors might occur.
Now, regarding your question, your code should be thread safe as long as your variables are defined within bar(), and bar() doesn't access some common resource such as a file.

You should post some example code to make sure we understand the use case.
For this example:
public class Test {
private String varA;
public void doSomething() {
String varB;
}
}
If you don't do anything to modify varA in this example and only modify varB, this example is Thread Safe.
If, however, you create or modify varA and depend on it's state, then the method is NOT Thread Safe.

Related

Are local variables thread safe?

there have been already similar questions, but it doesn't answer the following problem. It's well known that values of fields are not necessarily immediately synchronized between threads. But is this also the case with local variables? Can the IllegalStateException be thrown?
public static void main(String[] args) {
final Thread mainThread = Thread.currentThread();
final Integer[] shared = new Integer[1];
new Thread(new Runnable() {
#Override
public void run() {
shared[0] = 1;
mainThread.interrupt();
}
}).start();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
if (shared[0] == null) throw new IllegalStateException("Is this possible?");
}
}
Indeed, the value of shared will be the same for all threads. But the value of shared[0] also involves reading an array element, and that array element, like a field, may be subject to a data race.
Are you sure about shared being safe?
Yes, the Java Language Specification writes:
Local variables (§14.4), formal method parameters (§8.4.1), and exception handler parameters (§14.20) are never shared between threads and are unaffected by the memory model.
At the JVM level, each thread has its own local variables. If an anonymous class accesses a local variable of an enclosing method, the compiler rewrites this code to pass the value of the variable as a constructor parameter to the inner class, which will store it in a final field (this rewriting is why the compiler requires such a variable to be effectively final and definitely assigned), and replaces all accesses to this variable by an access to the final field. Due to the special guarantees the Java Memory Model gives for final fields, this access is safe even if it the object reference is published through a data race, provided that such publication only occurs after the object has completed construction.
Local variables are perfectly thread safe, because there is no way to share them with another thread in the first place.
Your example code is a wholly different beast, because you are actually asking about the value of a shared array referred to by a local variable. Thats two different things. The variable is perfectly safe (cannot change anyway, since its final), the contents of the array it refers to is not synchronized in any way, so its also not safe.
Edit: To elaborate a bit about your variable named "shared"
When you declare a local variable as final, java allows you to refer to that variable in the scope of an anonymous class defined within the visibility scope of said variable (Put simpler: from within the block where the variable was defined).
What looks like one variable, are actually two variables. The one you declared exists in the main thread. The moment the anonymous "new Runnable()" is created, a copy of the variable contents is made (it actually becomes a hidden final field in the anonymous class). So when you refer to "shared" within the run()-method you do not access the local variable "shared" in the main thread.
You can verify this by looking at the class files your example creates (there are two, one for the class, and one for the anonymous class) and use javap -v for both to have a look at the byte code generated.
Local variables that are visible to more than one thread are not thread safe. They have to be accessed through the regular mechanisms (synchronized, volatile, immutable, etc.).
Normally, you create a local variable and use it within one thread. When you are ready, you must Safely Publish that variable. After that point, all the normal thread safe mechanisms must apply.
Yes, local variables are thread safe because the are allocated in the stack. Threads, however, don't share the stack. They are unique for each variable.
shared is thread safe, its the state of the object it refers to thats not safe.
It's possible your main thread could throw that exception but highly unlikely.
Telling the anonymous thread start() does not necessarily mean the VM/OS will actually start your thread before the next part of the program executes. So your main thread could enter the sleep before the other thread even starts. If it got interrupted from an external event inside that sleep before the thread set the value you could end up with null.
The sleep on the main thread almost positively ensures the anon thread will run before the test of shared.
Think about what would happen if you removed the sleep and checked for null immediately after starting the new thread. On my system shared[0] was null about 50% of the times I ran your program modified to have the sleep removed.
public static void main(String[] args) {
final Thread mainThread = Thread.currentThread();
final Integer[] shared = new Integer[1];
new Thread(new Runnable() {
public void run() {
shared[0] = 1;
mainThread.interrupt();
}
}).start();
if (shared[0] == null)
System.out.println("ouch");
}
The local variables are stored in the stack and not in the heap, so they are thread safe

getting NullPointerException when using syncrhonized on null object

I have seen this NullPointerException on synchronized statement.
code:
synchronized(a){
a = new A()
}
So according to the above answer I have understood that it is not possible to use synchronized keyword on null reference.
So I changed my code to this:
synchronized(a = new A()){}
But am not sure if this is identical with my original code?
update:
what I want to achieve is lock the creation of a ( a = new A() )
Synchronized requires an object that will provide locking mechanism. It can be any object (in fact, synchronized without parameters will synchronize on this), but Java API provides classes dedicated to this functionality, for example ReentrantLock.
In code you provided every call to function containing synchronized block will use different object for locking, effectivly making synchronization useless.
Edit:
Since you updated your post with what you are actually trying to accomplish I can help you more.
public class Creator {
private A a;
public void createA() {
synchronized(this) {
a = new A();
}
}
}
I don't know if this fits your design since the code sample you provided is very small, but you should get the idea. Here instance of the Creator class is used to synchronize the creation of A. If you share it across multiple threads, each one of them calling createA(), you can be sure that one instantiation process will be finished before another one begins.
synchronized(a = new A()){}
so what it will do is it will create a new object of class A and use
that as Lock, so in simple word every thread can enter in synchronized
block anytime because each thread will have new lock and there will be
no other thread that is using that object as lock so every thread can
enter your synchronized block anytime and outcome will be no
synchronization
For Example
class TestClass {
SomeClass someVariable;
public void myMethod () {
synchronized (someVariable) {
...
}
}
public void myOtherMethod() {
synchronized (someVariable) {
...
}
}
}
here we can say Then those two blocks will be protected by execution
of 2 different threads at any time while someVariable is not modified.
Basically, it's said that those two blocks are synchronized against
the variable someVariable.
But in your case there will be always a new object so there will be no synchronization
These two code snippets are not equivalent!
In the first code snippet you synchronize on some object referenced by a, and afterwards you change the reference which will not change the synchronization object.
In the second snippet you first assign a newly created object to reference a and then synchronize on it. So the synchronization object will be the new one.
Generally, it is a very bad idea to change the reference which is used in the synchronized statement, regardless whether it is done inside the block (first code) or diretcly in the synchronized statement (second code). Make it final! Oh, and it mustn't be null, either.

Creating Object in a thread safety way

Directly from this web site, I came across the following description about creating object thread safety.
Warning: When constructing an object that will be shared between
threads, be very careful that a reference to the object does not
"leak" prematurely. For example, suppose you want to maintain a List
called instances containing every instance of class. You might be
tempted to add the following line to your constructor:
instances.add(this);
But then other threads can use instances to access the object before
construction of the object is complete.
Is anybody able to express the same concept with other words or another more graspable example?
Thanks in advance.
Let us assume, you have such class:
class Sync {
public Sync(List<Sync> list) {
list.add(this);
// switch
// instance initialization code
}
public void bang() { }
}
and you have two threads (thread #1 and thread #2), both of them have a reference the same List<Sync> list instance.
Now thread #1 creates a new Sync instance and as an argument provides a reference to the list instance:
new Sync(list);
While executing line // switch in the Sync constructor there is a context switch and now thread #2 is working.
Thread #2 executes such code:
for(Sync elem : list)
elem.bang();
Thread #2 calls bang() on the instance created in point 3, but this instance is not ready to be used yet, because the constructor of this instance has not been finished.
Therefore,
you have to be very careful when calling a constructor and passing a reference to the object shared between a few threads
when implementing a constructor you have to keep in mind that the provided instance can be shared between a few threads
Thread A is creating Object A, in the middle of creation object A (in first line of constructor of Object A) there is context switch. Now thread B is working, and thread B can look into object A (he had reference already). However Object A is not yet fully constructed because Thread A don't have time to finish it.
Here is your clear example :
Let's say, there is class named House
class House {
private static List<House> listOfHouse;
private name;
// other properties
public House(){
listOfHouse.add(this);
this.name = "dummy house";
//do other things
}
// other methods
}
And Village:
class Village {
public static void printsHouses(){
for(House house : House.getListOfHouse()){
System.out.println(house.getName());
}
}
}
Now if you are creating a House in a thread, "X". And when the executing thread is just finished the bellow line,
listOfHouse.add(this);
And the context is switched (already the reference of this object is added in the list listOfHouse, while the object creation is not finished yet) to another thread, "Y" running,
printsHouses();
in it! then printHouses() will see an object which is still not fully created and this type of inconsistency is known as Leak.
Lot of good data here but I thought I'd add some more information.
When constructing an object that will be shared between threads, be very careful that a reference to the object does not "leak" prematurely.
While you are constructing the object, you need to make sure that there is no way for other threads to access this object before it can be fulling constructed. This means that in a constructor you should not, for example:
Assign the object to a static field on the class that is accessible by other threads.
Start a thread on the object in the constructor which may start using fields from the object before they are fulling initialized.
Publish the object into a collection or via any other mechanisms that allow other threads to see the object before it can be fulling constructed.
You might be tempted to add the following line to your constructor:
instances.add(this);
So something like the following is improper:
public class Foo {
// multiple threads can use this
public static List<Foo> instances = new ArrayList<Foo>();
public Foo() {
...
// this "leaks" this, publishing it to other threads
instances.add(this);
...
// other initialization stuff
}
...
One addition bit of complexity is that the Java compiler/optimizer has the ability to reorder the instructions inside of the constructor so they happen at a later time. This means that even if you do instances.add(this); as the last line of the constructor, this is not enough to ensure that the constructor really has finished.
If multiple threads are going to be accessing this published object, it must be synchronized. The only fields you don't need to worry about are final fields which are guaranteed to be finished constructing when the constructor finishes. volatile fields are themselves synchronized so you don't have to worry about them.
I think that the following example illustrate what authors wanted to say:
public clsss MyClass {
public MyClass(List<?> list) {
// some stuff
list.add(this); // self registration
// other stuff
}
}
The MyClass registers itself in list that can be used by other thread. But it runs "other stuff" after the registration. This means that if other thread starts using the object before it finished its constructor the object is probably not fully created yet.
Its describing the following situation:
Thread1:
//we add a reference to this thread
object.add(thread1Id,this);
//we start to initialize this thread, but suppose before reaching the next line we switch threads
this.initialize();
Thread2:
//we are able to get th1, but its not initialized properly so its in an invalid state
//and hence th1 is not valid
Object th1 = object.get(thread1Id);
As the thread scheduler can stop execution of a thread at any time (even half-way through a high level instruction like instances.push_back(this)) and switch to executing a different thread, unexpected behaviour can happen if you don't synchronize parallel access to objects.
Look at the code below:
#include <vector>
#include <thread>
#include <memory>
#include <iostream>
struct A {
std::vector<A*> instances;
A() { instances.push_back(this); }
void printSize() { std::cout << instances.size() << std::endl; }
};
int main() {
std::unique_ptr<A> a; // Initialized to nullptr.
std::thread t1([&a] { a.reset(new A()); }); // Construct new A.
std::thread t2([&a] { a->printSize(); }); // Use A. This will fail if t1 don't happen to finish before.
t1.join();
t2.join();
}
As the access to a in main()-function is not synchronized execution will fail every once in a while.
This happens when execution of thread t1 is halted before finishing construction of the object A and thread t2 is executed instead. This results in thread t2 trying to access a unique_ptr<A> containing a nullptr.
You just have to make sure, that even, when one thread hasn't initialized the Object, no Thread will access it (and get a NullpointerException).
In this case, it would happen in the constructor (I suppose), but another thread could access that very object between its add to the list and the end of the constructor.

Synchronization concerns with a static method in java

Suppose I have a Utility class,
public class Utility {
private Utility() {} //Don't worry, just doing this as guarantee.
public static int stringToInt(String s) {
return Integer.parseInt(s);
}
};
Now, suppose, in a multithreaded application, a thread calls, Utility.stringToInt() method and while the operation enters the method call, another thread calls the same method passing a different s.
What happens in this case? Does Java lock a static method?
There is no issue here. Each thread will use its own stack so there is no point of collision among different s. And Integer.parseInt() is thread safe as it only uses local variables.
Java does not lock a static method, unless you add the keyword synchronized.
Note that when you lock a static method, you grab the Mutex of the Class object the method is implemented under, so synchronizing on a static method will prevent other threads from entering any of the other "synchronized" static methods.
Now, in your example, you don't need to synchronize in this particular case. That is because parameters are passed by copy; so, multiple calls to the static method will result in multiple copies of the parameters, each in their own stack frame. Likewise, simultaneous calls to Integer.parseInt(s) will each create their own stack frame, with copies of s's value passed into the separate stack frames.
Now if Integer.parseInt(...) was implemented in a very bad way (it used static non-final members during a parseInt's execution; then there would be a large cause for concern. Fortunately, the implementers of the Java libraries are better programmers than that.
In the example you gave, there is no shared data between threads AND there is no data which is modified. (You would have to have both for there to be a threading issue)
You can write
public enum Utility {
; // no instances
public synchronized static int stringToInt(String s) {
// does something which needs to be synchronised.
}
}
this is effectively the same as
public enum Utility {
; // no instances
public static int stringToInt(String s) {
synchronized(Utility.class) {
// does something which needs to be synchronised.
}
}
}
however, it won't mark the method as synchronized for you and you don't need synchronisation unless you are accessing shared data which can be modified.
It should not unless specified explicitly. Further in this case, there wont be any thread safety issue since "s" is immutable and also local to the method.
You dont need synchronization here as the variable s is local.
You need to worry only if multiple threads share resources, for e.g. if s was static field, then you have to think about multi-threading.

question about singleton classes and threads

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.

Categories