Volatile Object working - java

Consider below scenario, it says if str is volatile it means any update by any thread accessing str, will directly update on main stack instead of local Thread cache.
class A{
volatile String str;
volatile B b=new B();
}
class B{
int a;
C c;
}
For b volatile object, how scenario will work?
I read few links it says only reference is volatile and not the property of object itself, what does that mean, can some one help me with some example as I am finding it little bit difficult to understand.
if reference is synchronized, then how it will help, what is the use of it?

First scenario:
thread 1 does a.b = new B();
then thread 2 does B b = a.b;
In this case, you have the guarantee that the object referenced by b in the second thread is the new B() that the first thread has assigned to the variable.
Second scenario:
thread 1 does a.b.setFoo("hello");
then thread 2 does String s = a.b.getFoo();
In this case, you have no guarantee regarding the value of s in the second thread. It could be "hello", or it could be a previous value of a.b.foo (unless the foo attribute in class B is itself volatile, or the setters and getters are synchronized).

Related

Java non-final fields force visibility with another volatile field

I have recently begun to understand how the Java Memory Model works (I don't fully yet).
I now understand that if I have non-final, non-volatile fields in my classes then it is possible for the value of those fields to not be immediately visible to other threads post construction e.g.
public class Example {
Object a;
Object b;
public Example() {
this.a = new Object();
this.b = new Object();
}
}
Example e = new Example();
// now imagine we are in another thread
e.a // could this in theory be null?
e.b // could this in theory be null?
What I'm not sure about is weather if I add a third volatile variable and set it at the end will the writes to a and b be guaranteed to be visible to other threads?
public class Example2 {
Object a;
Object b;
volatile Object c;
public Example2() {
this.a = new Object();
this.b = new Object();
this.c = new Object();
}
}
// some where else
Example2 e2 = new Example2();
// are e2.a and e2.b guaranteed to be visible to all other threads? I know (e2.c will be)
This is not something I particularly want to use but I want to understand what would happen in this case.
The constructor runs in a single thread and the instance is not "visible" to other threads until the constructor completes.
So, in this example, a and b will only be seen in other threads as null if they are subsequently set to null post-constructor.
The volatile keyword addresses possible optimizations in which a thread may continue to use an old value for a field after it changes on another thread due to local caching of the value. By adding volatile to the field, such optimizations are disabled.
By the way, if there's a need to synchronize across threads, using volatile fields is not ideal. Using atomic classes or other constructs from java.util.concurrent is advisable.

Is super.clone() of Cloneable a thread safe method?

If I have a class Foo
public class Foo implements Serializable, Cloneable {
public Foo() {}
protected String s;
protected int n;
public Foo clone() {
return (Foo) super.clone();
}
public String getS() {
return s;
}
public void setS(String s) {
this.s = s;
}
public String getN() {
return n;
}
public void setN(int n) {
this.n = n;
}
}
And it's used in MyClass and the handler is passed to two thread A and B what appens if at the same time thread A try to clone the handler and thread B try to change a public variable of the handler?
E.g.
Foo Class
s = "Hello"
n = "42"
This class is passed to A and B that run at the same time.
A wants clone Foo Class and after 1 µs B wants change n to 43.
The clone result will be s = "Hello" and n = "42" || n = "43"?
More simpler: super.clone() is thread safe or I have to use lock or synchronized? In case I have to use lock or synchronized which is the best way to use them?
You are slightly misusing the term "thread-safe". It does not mean "synchronized", and that's apparently how you are using it. No amount of synchronization can prevent implementation errors from breaking thread safety. As an example, any code you wrote which mutates the object while not holding any lock will clearly violate thread safety of the object, and there is nothing a library method like Object.clone can do about that.
Ultimately, thread safety is always in the hands of the implementor and Object.clone() will not do anything to make that harder for you: all it does is read the state of the current object and copy it to the new object. It does not publish that new object.
clone is not specifically described as thread-safe, which means it's not. If one thread is cloning the object while another thread is changing it, the clone can end up in an inconsistent state.
You could grab a lock in your clone function, but much better would be to grab it in the code which calls clone.
No it is not thread safe if two threads are trying to execute this method over the same instance of Foo.
You should create a mutex using this instance .For example place the code which executes this clone method in synchronized(fooInstance) block.

Which variables are thread safe?

I am having a Servlet A which defines a local variable say a1 in one of its method as shown below. There is another class B for which object is created in Servlet A and that object calls the method and do operation.
Which one of these variable a1 and a2 is thread safe and why? I believe that a1 is thread safe since that is local to class A and a2 is not thread safe since that is behaving as a member variable.
class Servlet A {
public void method1(){
String a1;
B b = new b();
String c = b.method2(a1);
}
}
class B {
String a2;
public String method2(String a1){
// do operations on a1 and a2
return a1+a2;
}
}
You are right. Method-scoped variables (local variables) are thread safe, because they live on stack and couldn't be accessed by other threads.
Member variables (fields) live on heap and are not thread-safe, because they could be accessed simultaneously by multiple threads.

Is lazy initialization with immutable data always thread-safe?

I have two classes A and B:
class A {
private final String someData;
private B b;
public String getSomeData() { return someData; }
public B getB() {
if (b == null) {
b = new B(someData);
}
return b;
}
}
where B is immutable and computes its data only from an instance of A. A has immutable semantics, but it's internals are mutable (like hashCode in java.lang.String).
When I call getB() from two different threads, and the calls overlap, I assume each thread gets its own instance of B. But since the constructor of B gets only immutable data, the two instances of B should be equal.
Is that correct? If not, must I make getB() synchronized to make it thread-safe?
Assume that B implements equals(), which compares all instance variables of B. Same for hashCode()
This is not thread-safe, because you haven't created any "happens-before" relationships with volatile or synchronized, so it's possible for the two threads to interfere with each other.
The problem is that although b = new B(someData) means "allocate enough memory for an instance of B, then create the instance there, then point b to it", the system is allowed to implement it as "allocate enough memory for an instance of B, then point b to it, then create the instance" (since, in a single-threaded app, that's equivalent). So in your code, where two threads can create separate instances but return the same instance, there's a chance that one thread will return the other thread's instance before the instance is fully initialized.
For "But since the constructor of B gets only immutable data, the two instances of B should be equal."
As you understand its not thread safe, one thread might get un-initialized B instance (B as null or inconsistent state where somedata not yet set) others might get b instance with somedata set.
To fix this you need synchronized getB method or use synchronized block with double-check lock or some non-blocking technique like AtomicReference. For you reference I am adding here sample code for how to achieve the correct threadSafe getB() method using AtomicReference.
class A {
private final String someData = "somedata";
private AtomicReference<B> bRef;
public String getSomeData() { return someData; }
public B getB() {
if(bRef.get()== null){
synchronized (this){
if(bRef.get() == null)
bRef.compareAndSet(null,new B(someData));
}
}
return bRef.get();
}
}
class B{
public B(String someData) {
}
}

Static method access to a non static variable inside a thread

I have:
public class UTIL{
public static void met(){
do_something(){
print(A.m());
}
}
}
public class A{
public <type> m;
public <type>static m(){
return m;
}
}
Now:
Thread A contains instance of class A
Thread B contains instance of class A
From Thread B, at some point UTIL.met is called.
Question:
When UTIL.met is called, will it use m from the instance of A in Thread B?
When UTIL.met is called, will it use m from the instance of A in Thread B?
No, it doesn't matter if Thread A has one instance and Thread B has another. A.m is static and common for all instances.
But it is definitely the case that if the variables are static, then both threads will use the same variable.
(In other words, without proper synchronization, you'll have nasty race-conditions.)
m is a class variable, so is is actually common for all instances.
UTIL.met() will use the same instance of m that is "being held" [or can be accessed is a better terminology...] in all instances of A.
m is defined as a static variable in A. So it will common/shared among all instances of A.
If m is not static on the other hand, then of course each instance will have its own copy.
Well since thread A and thread B each contains own instance of class A, then each thread will use its instance of A.
is that what you want to achieve or you wanted to share m between instances??

Categories

Resources