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) {
}
}
Related
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.
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.
I have static method when multiple threads are accessing , will the data updated incorrectly,
public class A
{
private static B b=null;
public static B create()
{
b= new B();
return b;
}
public static B process()
{
// doing some processing with b;
return b;
}
}
If multiple threads are accessing simultaneously, Will B get affected?
If you want to protect the value and ensure it is updated correctly, then you should make the method synchronized.
No, because b exists on object level and is not statically accessible.
No one can tell until we see the way you access and work on b.
However, one thing I can tell is, static or not is usually not a main factor that affect thread-safetiness.
In the below code, are b and show inherently static?
public class A {
public static class B {
private int b = 0;
public void show() {
System.out.println(b);
}
}
}
No they aren't static. You need to create an instance of B to access them.
The static keyword in your code example means that instances of B can be created without an instance of A.
If B was not static:
Instances would have an implicit reference to an instance of A.
The only way to create them would be to use new B() inside class A, or using syntax like new A().new B().
Methods in B can refer to A.this (the implicit reference to an instance of A).
Methods in B can refer to A.this.someField (using that implicit reference).
Methods in B can call instance (non-static) methods in A.
However, because B is static:
Instances do not have a reference to an instance of A - you don't need an A to create a B.
Instances can be created using new A.B() (or just new B() from within in class A)
Methods in B cannot refer to A.this.
Methods in B cannot access fields in A (unless passed in as a parameter).
Methods in B cannot call instance (non-static) methods in A.
They are not static. They are instance fields in B.
Meaning you need to have an instance of B to get/set them.
B is static in A but that does not make those fields of B static.
You can create many instances of B without any reference to A.
So B is static class in A but the same is not true for B's instance fields.
The static keyword has two meanings that are actually quite different and that can be confusing.
Static on a variable/method means that it exists at the class level, not the instance level. This means that you only have one copy of that variable/method no matter how many instances of the class you create.
Static on an inner class though just means that the class does not depend upon its outer class. In your example you can create a new B() without having an A. If you didn't have the static keyword on the class you could not create a new B() unless it was within an instance of A.
B is a static inner class of A.
Need to instantiate B.
A.B innerObject = new A.B();
innerObject.show();
The identifier static has a specific purpose here that many people don't immediately grasp. I'm going to take your code and change it a bit.
public class A {
private int a;
public A(int a) {
this.a = a;
}
public class B {
public void show() {
System.out.println(a);
}
}
}
Now, what's happening in class B? Because B is a non-static class, it has access to other non-static members in class A. Essentially, it states that every class A object has their own flavor of class B objects, even thought they are functionally the same. For us to get that same behavior if B was a static class:
public class A {
private int a;
public A(int a) {
this.a = a;
}
public int getA() { return a; }
public static class B {
public void show(A a) {
System.out.println(a.getA());
}
}
}
Here, this implies that the flavor of B objects doesn't change depending on which A object created it. The B class is static so that it cannot access non-static members of the A class object that created it and must access those members explicitly from whichever A object it wants to interact with.
In the previous implementation, a B object would seamlessly access fields and non-static methods of the A object that created it.
These are two different behaviors and often it's clear exactly which one fits your objective.
I was asked this question in an interview . I have a base class (say class A) and then two subclasses B and C. Now I have no control over the constructor of B and C(those constructors can't be private , has to be public ) but the requirement is that every instance of B and Cshould be a singleton . How can I achieve this ?
I think I'd do this in the constructor for A. Get it to call this.getClass(), and use that to do a lookup in private HashSet. If you get a hit, then an instance of the class has previously been created, and you throw an exception.
public abstract class A {
private static HashSet<Class<?>> classes = new HashSet<Class<?>>();
public A () {
synchronized (classes) {
Class<?> c = this.getClass();
if (classes.contains(c)) {
throw NotSingletonException("Class " + c + " is not singleton");
}
classes.add(c);
}
}
}
If you arrange that all of A's constructors do this, then subclasses cannot avoid the check. And since the JLS won't let you put a try / catch around a this() or super() call, the constructor for the subclass can't ever return normally once that exception has been thrown.
I'd say that this is a pretty hard interview question ...
#emory comments:
What if B and C are not final? Then I could create classes B1, B2, C1, C2, etc.
The problem here (if it counts as a problem) is that the B1 and B2 instances are also B instances, and that means that the B instance is no longer a singleton ... depending on the definition of singleton you are aspiring to implement.
I can see a couple of ways of dealing with this:
You could reflectively test the subclass modifiers see if the classes are final, and refuse to create instances of non-final classes ... just in case.
You could replace the HashSet<Class> with a List<Class>. Then each time the A constructor is called, it would iterate over the list calling elem.isAssignableFrom(c) for each element class. If any call returns true, the (strict) singleton invariant is violated so an exception should be thrown.
The logic may need to be adjusted depending on the model of singleton-ness you are trying to enforce, but the general solution applies: record the classes and examine / compare new classes with previous ones.
I am showing it for the class B
Though you can use Double checked locking, and synchronized on method to do it.. i am showing you a quick and dirty way of doing it...
public class B {
private static B b = new B();
private B() {}
public static B getInstance() {
return b;
}
}