What objects to synchronize on? Why are local variables bad? [duplicate] - java

This question already has answers here:
Clarification on the meaning of the parameter block synchronization
(3 answers)
What does 'synchronized' mean?
(17 answers)
How does synchronized work in Java
(4 answers)
Closed 2 years ago.
There is a lot of material on stack-overflow about synchronization, but I still haven't acquired quality content about deciding which object to use as an intrinsic lock. Can some one actually make a good answer as a rule of thumb?
So should I choose 'monitor' as an instance variable or local variable or instance owning the method? All three of them do the job well. Also primitive value wrapper classes use 'pools' so no problem there as well, as threads 'attack' the same lock.
So why is it better to do this (this):
class A {
void methodA(){
synchronized (this){
//some code
}
}
}
over this(instance variable):
class A {
String monitor = "monitor";
void methodA(){
synchronized (monitor){
//some code
}
}
}
or over this(local variable):
class A {
void methodA(){
String monitor = "monitor";
synchronized (monitor){
//some code
}
}
}
They all work fine/same. So why did I read that I should avoid local variables when they implicitly use pools to store objects? What matter does the scope of variables make in this case?
Thanks!

You should avoid using the monitor of objects stored in local variables because typically only the current thread has access to objects stored in local variables. But since in this particular case, the local variable actually holds a globally shared object from the constant pool, you don't suffer from that particular problem.
The problem with using monitors of constant pool objects like here:
String monitor = "monitor";
void methodA() {
synchronized (monitor){
//some code
}
}
... is that there is only one pooled constant object.
Two different threads operating on two different instances of class A cannot enter the synchronized block in methodA at the same time, even if you've ensured it should be safe (for example, you don't touch static shared state).
What's even worse: there might be some other class B somewhere else, which also happens to synchronize on the constant "monitor" string. Now a thread using class B will block other, unrelated, threads from using class A.
On top of that, it's incredibly easy to create a deadlock because you are unknowingly sharing locks between threads.

Related

Java thread safety of setting a reference to an object

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.

Do different threads see the same version of a object referenced by a local variable?

Are multiple threads guaranteed to see the same version of a shared object to which they have a reference? Here is a code sample:
public static void main(String[] args) {
final AtomicBoolean flag = new AtomicBoolean(false);
new Thread(){
public void run() { possibly read and mutate flag }
}.start();
new Thread(){
public void run() { possibly read and mutate flag }
}.start();
while (!flag.get()) {
Thread.yield();
}
}
To be clear, I am wondering whether writes by the child threads to the shared object are seen by the parent and sibling threads.
Are multiple threads guaranteed to see the same version of a shared local variable in their scope.
In general, it depends on what you mean by "the same version". It also depends on the nature of the variable (e.g. how it is declared and initialized) ... and on how the threads use it.
(In general, Java doesn't do "versions" of variables. A thread accessing a shared variable or object will either see the latest state, or it won't. If it sees a state that isn't the latest state, then there are no guarantees as to what it will see. In particular, it may see something that doesn't directly correspond to any notional version of the object ... due to word-tearing and other cache-related memory artefacts.)
In your example you are using a final local variable within an inner class (in this case you have two anonymous inner classes). When you do that, the compiler creates a corresponding synthetic variable in the inner class that is initialized with the value of the variable in the method scope. The compiled inner class then refers to the value of the synthetic variable instead of the original variable.
In your example, it is guaranteed that the inner classes (e.g. your threads) will see the same (reference) value as in the original variable. Furthermore, it is guaranteed that they will (at least initially) see a consistent snapshot of whatever object it is that it references. (And since it is an AtomicXxxx class, it will always be consistent for all threads that can access it. Guaranteed.)
OK, so what about other cases:
If flag was a static or instance field that was also final, then we wouldn't have synthetic variables, and each nested class would be referencing the same shared variable. But it would all still work.
If flag was a static or instance field and it wasn't final, but nothing changed the field (after creating of the threads) then it would still be OK. (Though you could argue that this is fragile ... because something could change the field.)
If flag was a static or instance field and it wasn't final or volatile, then the threads would initially see the same state as the parent thread. But if either the original thread or any of the other threads changed the variable (etcetera), then the others are not guaranteed to see the new state ... unless they respective threads synchronize properly.
I would like to know if changes to flag made in one thread are seen immediately by the other two threads.
As I said above, it depends ...
In your example, the answer is "yes", because you use a final reference to AtomicBoolean.
If you had declared flag as a boolean and marked it as volatile, then the answer would be "yes".
If you had declared flag as a boolean and non-volatile, then the answer would be "no".
If flag was a final reference to an ordinary object with a mutable non-volatile boolean field, then the answer would also be "no". (The threads would all see the same object, but they wouldn't consistently see the latest state. The solution would be to use synchronized getters and setters, or equivalent.)
Yes, the two threads share the same final AtomicBoolean which is a class used to set the truth value. The variable flag itself can't be recreated because it is final. But you can perform actions on it to set value. Just like a final int[] can't be assigned to different size but you can change the value of what's inside.
final AtomicBoolean flag = new AtomicBoolean(false);
new Thread(){
public void run(){
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
flag.set(true);
}
}.start();
new Thread(){
public void run(){
flag.set(false);
}
}.start();
Thread.sleep(200);// comment this line, you see different results
System.out.println(flag);
In this case, yes. The Java Language Specification says that calling Thread.start() synchronizes-with all previous actions on the calling thread:
An action that starts a thread synchronizes-with the first action in the thread it starts.
This creates a happens-before relationship between all writes on your main thread (including any writes the constructor of the AtomicBoolean made to initialize itself) are made visible to the thread your main thread started.
A call to start() on a thread happens-before any actions in the started thread.
So basically you are good to go. Your AtomicBoolean object is visible to both threads, and they both see the same object.
This pattern is called Safe Publication, btw. You use it to safely publish an object you create (like your AtomicBoolean) so that other threads can see it. (And yes, Thread.start() isn't on the list there of ways to safely publish an object because Thread.start() isn't general enough. But it's the same idea, and works the same way.)
The local variable is not shared1, and being final means that there would be no worry of it changing even if it was the case. (A question about member variables would result in a different response although, excluding constructor leakage, a final member would provide the same guarantees.)
The same object is shared across threads; it will be the same object and will adhere to the defined AtomicBoolean contract.
A boolean value that may be updated atomically. See the java.util.concurrent.atomic package specification for description of the properties of atomic variables.
In short the package documentation specifies the following which in turn guarantees happens-before relationships.
get has the memory effects of reading a volatile variable.
set has the memory effects of writing (assigning) a volatile variable.
There are many questions relating to the thread-safey of volatile (and AtomicXYZ objects), eg. see Is a volatile int in Java thread-safe? and Is AtomicBoolean needed to create a cancellable thread?
1 Anonymous types, including Java 8 lambdas, do not create closures/lexical bindings to variables in scope and as such are not capable of sharing local variables; rather variables are synthesized with the value of the final (or effectively final) variable from the enclosing scope which is bound when the anonymous type is instantiated.

Singleton Pattern in java [duplicate]

This question already has answers here:
Java: Lazy Initializing Singleton
(5 answers)
Closed 9 years ago.
I was going through design pattern and came across with Singleton Pattern
class SingletonPattern implements Runnable {
private static SingletonPattern single=null;
private SingletonPattern() { }
public synchronized static SingletonPattern getInstance() {
if(null==single) {
single=new SingletonPattern();
}
return single;
}
}
Now I understand that synchronized will help that two thread cannot access the getInstance method but correct me if I am wrong two different object will have two locks each having one.Another thread can be started from anther object and get then access the getInstance() method thus we can have two objects.??
No. The synchronized method will prevent 2 threads from simultaneously calling the method. You can read up on synchronized here. In case of a static method, the synchronized acts on the class rather than object.
However, this way of making Singletons is inefficient. And Double Checked Locking is broken. The best way to do singletons in java is by using a Enum
The variable single is static. That is to say, all instance of class SingletonPattern share the same variable single. The first time the function getInstance() execute, the variable single is null, so
single = new SingletonPattern();
executes, which makes variable single not null any more.
Then all the successive call of function getInstance() would not enter the if clause, thus only return the same variable single, which is a reference to the same instance of the class SingletonPattern.
Also the synchronized keyword makes sure the function getINstance() would not be called in two threads at the same time.
No. Since getInstance and single are static both threads will use the very same method and object so there won't be two objects. synchronized will ensure that they won't access simultaneously inside getInstance
synchronized static method will acquire Class lock and there is a single class lock available for all objects of this class. Hence different objects will be prevented from acquiring this lock at the same time.
But this mechanism works as long as different classloaders are not involved.
Although best way to implement singletons in java is to use enums

synchronized(this) vs synchronized(MyClass.class) [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Java Synchronized Block for .class
I was reading through an article on synchronization. I am confused on below points and need more clarification
For synchronization block. How
synchronized (this) {
// code
}
differs from
synchronized (MyClass.class) {
// code
}
Synchronizing instance method means threads will have to get exclusive lock on the instance, while synchronizing static method means thread will have to acquire a lock on whole class(correct me if I am wrong). So if a class has three methods and one of them is static synchronized then if a thread acquires lock on that method then that means it will acquire lock on the whole class. So does that mean the other two will also get locked and no other method will be able to access those two methods as the whole class is having lock?
MyClass.class and this are different things, they are different references to different objects.
this - is a reference to this particular instance of the class, and
MyClass.class - is a reference to the MyClass description object.
These synchronization blocks differ in that the first will synchronize all threads that deal concretely with this instance of MyClass, and the second one will synchronize all threads independently of which object on which method was called.
The first example (acquiring lock on this) is meant to be used in instance methods, the second one (acquiring lock on class object) -- in static methods.
If one thread acquires lock on MyClass.class, other threads will have to wait to enter the synchronized block of a static method that this block is located in. Meanwhile, all of the threads will be able to acquire lock for a particular instance of this class and execute instance methods.

Please Explain How Java synchronized work with static method? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Java synchronized methods: lock on object or class
Please Explain How Java synchronized work with static method ? Some one has said that it is done by its Class Object but they don't say how the lock is done with that.
You always synchronize on a monitor object. Every Java object can be used here.
With a synchronized block, you can specify that object directly.
synchronized (something){
}
With a synchronized method, it synchronizes on the object instance itself (on this), so it is identical to:
synchronized (this) {
}
With a synchronized static method, it synchronizes on the class object, just like "some one has said".
synchronized (ThisClass.class){
}
The mechanism is always the same: Only one thread can hold the lock at the same time, others have to wait.

Categories