I have a strategy pattern implementation as below:
public class ConcreteStrategy implements Strategy {
public static final Strategy INSTANCE = new ConcreteStrategy();
public AClass execute(AClass aClass){
//...do somthing
return aClass;
}
}
Ignoring the bad practice of returning the input parameter, is static instance INSTANCE use thread safe?
Assuming ConcreteStrategy isn't modified, or is modified only in a thread-safe way, then yes. The final modifier will ensure (in Java 1.5+) that all threads see the INSTANCE object in at least the state it was in when the class was initialized. Any subsequent change to the object would need to be made thread-safe in the usual way (through volatiles, synchronization, classes that provide thread-safety, etc).
Generally any Object in java that is immutable or stateless is Thread-safe.
Your example is almost thread safe.
The reference to INSTANCE is thread-safe, since it's final. But the contents of the ConcreteStrategy might be very well not Thread safe (we do not see the code, thus can't tell).
If you provide proper synchronization to the ConcreteStrategy Object, then it could be very well a Thread safe Object.
Cheers, Eugene.
Related
I have a code which is as below
class classA {
int sum = 0;
void recursiveMethodA {
sum = sum +1; // For simplicity
}
}
Basically I am doing some operation in a recursive method which runs lets say 10 times and changing state at class level. But this class is not thread safe.
Now in order to make it thread safe I am thinking of a below option.
class class B {
// Public exposed method
public void methodB {
ClassA classA = new ClassA();
classA.recursiveMethodA();
}
}
My logic is that since I am creating object of class A inside a method of class B, it is created on stack instead of heap and hence it is thread safe.
Is this logic correct? Please suggest alternate options.
My logic is that since I am creating object of class A inside a method of class B, it is created on stack instead of heap and hence it is thread safe.
Your logic and/or terminology are not correct. In fact, the instance of ClassA is in the heap. All regular Java objects are created in the heap!
Your code is actually thread-safe, but the correct explanation is as follows:
The object is created, and the only reference to it is assigned to a local variable.
By inspection, no other thread can ever see that variable.
By inspection, the object reference is never passed to another thread; i.e. it is not published.
The points 1., 2., and 3. mean that the object is thread confined1 for its entire lifetime.
Since the object is thread confined, it is not necessary to consider thread-safety.
It is not sufficient to say (just) that a local variable is used:
There are scenarios where another thread can see the value of a local variable; e.g. if a lambda or inner method closure is created and passed to another thread.
It is also necessary to consider that the value in the variable could be passed to another thread.
Finalization and reference processing will be done on another thread. However, this should NOT present a thread-safety concern. (The JLS spec takes care of finalization, and the javadocs for Reference take care of references. In both cases, there is a happens before at the appropriate points.)
1 - This is a fancy way of saying that no other thread can ever see it the object and its reference.
Do you mean classA is thread safe by itself?
No. It is not thread safe by itself. It is thread safe in this particular context. Or more to the point, thread safety is moot in this context ... because the instance is thread confined.
Shouldn't I define the class as thread safe in all the contexts? I don't know how tomorrow it can be used?
That is up to you!
But consider this: a large number of standard Java classes are NOT thread-safe ... by design. Indeed the classic case is StringBuilder which is the non-thread-safe reimplementation of StringBuffer. Others are most of the collection types in java.util!
Basically, you have two choices:
Make a class inherently thread-safe, and accept that this comes with runtime overheads.
Make a class inherently non-thread-safe, and make sure that you only use it ways that deal with this appropriately. (One way is to thread confine the instances. Another is to use some form of external synchronization.)
The simplest way to have a threadsafe function is put keyword "synchronized"
synchronized public void method() {
//do something
}
In the classic "Java concurrency in Practice" Brian Goetz uses the following snippet of code to demonstrate how to safely publish an object using a private constructor and a factory method:
public class SafeListener {
private final EventListener listener;
private SafeListener() {
listener = new EventListener() {
public void onEvent(Event e) {
doSomething(e);
}
};
}
public static SafeListener newInstance(EventSource source) {
SafeListener safe = new SafeListener();
source.registerListener(safe.listener);
return safe;
}
}
What I can't figure out yet is how this code achieves safe publication through a private constructor.
I am aware that a private constructor is used to prevent instantiation outside of the object but how does that apply to a thread rather than an object? A thread is not necessarily an object and I can't see what stops another thread from acquiring a reference to safe before the constructor finishes execution.
The constructor’s property of being private has nothing to do with the thread-safety. This is an example of the final field publication guaranty. In order for it to work, the this instance of the final field must not escape during the constructor, therefore the factory method takes care of constructing the holder instance first and registering the listener afterwards. It’s natural for applications of the factory pattern to have private constructors and public factory methods but that is not important to achieve the thread-safety here.
It’s all about how JIT and the HotSpot optimizer treat the code when performing the optimizations. They know what final or volatile fields are and what a constructor is. They will obey the limitations to the degree of optimization of such constructs. Most important, they ensure that all writes to an object you store in the final field and the write to the final field itself happen-before the constructor ends so that the final field stores happen-before any effect of the registerListener invocation in your example. Therefore, other threads can’t see the listener reference before its correct initialization.
Note that this is something you should rarely rely on. In your example, if the method registerListener of the EventSource is not thread-safe, still very bad things can happen. On the other hand, if it’s thread-safe, its thread-safety will apply to the listener constructed before the registration as well so the final field guaranty would not be needed.
Point here is to prevent escapement of this till constructor is finished. To this end, constructor is made private and factory method is provided which takes care of registering listener in external code, after object's constructor finished.
An example of thread-safe API.
how does that apply to a thread rather than an object? A thread is not necessarily an object and I can't see what stops another thread from acquiring a reference to safe before the constructor finishes execution.
A Thread is always an object in the java.lang.Thread sense, of course. The pattern should not be applied to a thread itself. Instead, it could be applied for cases where a new Thread has to be started "together" with the construction of an object. Starting the thread IN the constructor can allow the reference to the incompletely constructed object to escape. However, with this pattern, the newly constructed instance is trapped in the newInstance method until its construction is entirely complete.
(Or to put it that way: I can't imagine how another thread should acquire a reference to the safe instance before its construction is complete. Maybe you can give an example how how you think this might happen.)
Reading this site, I've found this:
[The] line private static final Foo INSTANCE = new Foo(); is only executed when the class is actually used, this takes care of the lazy instantiation, and is it guaranteed to be thread safe.
Why this guaranteed to be thread safe? Because this field is final? Or for some other reason?
Because it's final, yes. Final variables have special thread-safety semantics, in that other threads are guaranteed to see the final field in at least the state it was in when its constructor finished.
This is in JLS 17.5, though the language there is a bit dense. These semantics were introduced in Java 1.5, in particular by JSR-133. See this page for a non-spec discussion of JSR-133 and its various implications.
Note that if you modify the instance after its constructor, that is not necessarily thread safe. In that case, you have to take the usual thread safety precautions to ensure happens-before edges.
I'm fairly sure (though not quite 100%) that the fact that only one thread does the class initialization is not a factor here. It's true that the class is only initialized by one thread, but I don't believe there are any specific happens-before edges established between that thread any any other thread that uses the class (other than that other thread not having to re-initialize the class). So, without the final keyword, another thread would be able to see a partially-constructed instance of the object. The specific happens-before edges the JMM defines are in JLS 17.4.5, and class initialization is not listed there.
Class constructors and static/instance initializers are guaranteed to be atomically executed and since private static final FOO INSTANCE = new FOO; is equivalent to
private static final FOO INSTANCE;
static{
INSTANCE = new FOO();
}
this case falls in the above category.
It is guaranteed to be thread safe because the JVM guarantees that static initializers are executed on a single thread.
It doesn't mean that the instance of Foo is internally thread safe- it just means that you are guaranteed that the constructor of Foo will be called exactly once, on one thread, via this particular code path.
The static initialisation block of any class is guaranteed to be single threaded. A simpler singleton is to use an enum
enum Singleton {
INSTANCE;
}
This is also threads safe and the class lazy-initialised.
I am referring to the solution for the Singleton Pattern by Bill Pugh on Wikipedia:
public class Singleton
{
// Private constructor prevents instantiation from other classes
private Singleton() {}
/**
* SingletonHolder is loaded on the first execution of Singleton.getInstance()
* or the first access to SingletonHolder.INSTANCE, not before.
*/
private static class SingletonHolder
{
private static final Singleton INSTANCE = new Singleton();
}
public static Singleton getInstance()
{
return SingletonHolder.INSTANCE;
}
}
Here they have mentioned:
The inner class is referenced no earlier (and therefore loaded no earlier by the class loader) than the moment that getInstance() is called. Thus, this solution is thread-safe without requiring special language constructs (i.e. volatile or synchronized).
However, isn't there a possibility that 2 threads would call getInstance() at the same time, which would lead to two instances of singleton being created? Isn't it safe to use synchronized here? If yes, where should it be used in the code?
See the "How it works", in the article "Initialization on demand holder idiom" linked from the same section.
In a nutshell, here's what happens when you call getInstance() the first time:
The JVM sees a reference to SingletonHolder it has never seen referenced before.
Execution is paused while it initializes SingletonHolder. This includes running any static initialization, which includes the singleton instance.
Execution resumes. Any other threads calling getInstance() at the same time will see that SingletonHolder is already initialized. The Java spec guarantees that class initialization is thread-safe.
The JLS guarantees the JVM will not initialize instance until someone calls getInstance(); and that will be thread safe because it would happen during the class initialization of SingletonHolder.
However, since Java 5, the preferred approach involves Enum:
// Enum singleton - the preferred approach
public enum Elvis {
INSTANCE;
public void leaveTheBuilding() { ... }
}
Reference: Implementing the singleton pattern in Java
Here is the explanation from Wikipedia on this phenomenon (emphasis mine):
When the class Something is loaded by
the JVM, the class goes through
initialization. Since the class does
not have any static variables to
initialize, the initialization
completes trivially. The static class
definition LazyHolder within it is not
initialized until the JVM determines
that LazyHolder must be executed. The
static class LazyHolder is only
executed when the static method
getInstance is invoked on the class
Something, and the first time this
happens the JVM will load and
initialize the LazyHolder class. The
initialization of the LazyHolder class
results in static variable something
being initialized by executing the
(private) constructor for the outer
class Something. Since the class
initialization phase is guaranteed by
the JLS to be serial, i.e.,
non-concurrent, no further
synchronization is required in the
static getInstance method during
loading and initialization. And since
the initialization phase writes the
static variable something in a serial
operation, all subsequent concurrent
invocations of the getInstance will
return the same correctly initialized
something without incurring any
additional synchronization overhead.
So in your example, Singleton is "LazyHolder" and SingletonHolder is "Something". Calling getInstance() twice will not cause a race condition due to the JLS guarantees.
I think the idea is that Java guarantees that a class can only be initialized once, so implicitly only the first thread to access would cause this to happen
The Singleton is created when Singleton.getInstance() is called at this time the INSTANCE will be instantiated.
Synchronization depends on a conrete implementation, since there are no values to modify (in this example) no synchronization is required.
There are two differences here that need to be noted. The first is the Singleton design pattern and the other is a singleton instance.
The Singleton design pattern is problematic due to the fact that the design pattern represents a singleton instance as is implemented using static state (which is a bad thing for a variety of reasons - especially with unit testing). The second is an instance for which there is only one instance, no matter what (like the JVM singleton implemented as an enum).
The enum version is definitely superior, when compared to the Singleton pattern.
If you don't want to implement all instances as enum instances, then you should think about using Dependency Injection (frameworks such as Google Guice) to manage the singleton instances for the application.
This idiom is known as the Initialization on Demand Holder (IODH) idiom and is discussed in Item 48 of Effective Java as reminded by Bob Lee in his great post about Lazy Loading Singletons:
Item 48: Synchronize access to shared mutable data
(...)
The initialize-on-demand holder
class idiom is appropriate for use
when a static field is expensive to
initialize and may not be needed, but
will be used intensively if it is
needed. This idiom is shown below:
// The initialize-on-demand holder class idiom
private static class FooHolder {
static final Foo foo = new Foo();
}
public static Foo getFoo() { return FooHolder.foo; }
The idiom takes advantage of the
guarantee that a class will not be
initialized until it is used [JLS,
12.4.1]. When the getFoo method is
invoked for the first time, it reads
the field FooHolder.foo, causing the
FooHolder class to get initialized.
The beauty of this idiom is that the
getFoo method is not synchronized
and performs only a field access, so
lazy initialization adds practically
nothing to the cost of access. The
only shortcoming of the idiom is that
it does not work for instance fields,
only for static fields.
However, in the Second Edition of Effective Java, Joshua explains how enums can be (ab)used for writing a serializable Singleton (this should be the preferred way with Java 5):
As of release 1.5, there is a third approach to implementing singletons. Simply
make an enum type with one element:
// Enum singleton - the preferred approach
public enum Elvis {
INSTANCE;
public void leaveTheBuilding() { ... }
}
This approach is functionally equivalent to the public field approach, except that it
is more concise, provides the serialization machinery for free, and provides an
ironclad guarantee against multiple instantiation, even in the face of sophisticated
serialization or reflection attacks. While this approach has yet to be widely
adopted, a single-element enum type is the best way to implement a singleton.
class A {
public synchronized void myOneMethod() {
// ...
}
}
class B extends A {
public synchronized void myOtherMethod() {
// ...
}
}
// ...
B myObject;
// ...
myObject.myOneMethod(); // acquires lock
myObject.myOtherMethod(); // same lock?
How I understand the synchronization model, I'd say that yes, it does, because the lock / monitor is associated with the instance myObject, and it doesn't matter where the method was defined. But am I right? If not, why? If yes, why are you sure, and I'm not? :-)
Yes, you are right, and you got the explanation right too. Nothing much to add.
Note that if the methods were static, then they would synchronize on different objects, namely their respective classes (A and B).
EDIT: Why am I sure? I don't know, why are you not sure? ;-) myObject is just one object - there isn't any distinction between the myObject attributes that come from class A and those that come from class B. (Well, technically you could probably use reflection to find out which are which, so there must be some distinction, but forget about reflection for now. For common operations on the object there's no distinction.)
Yes, synchronized is equivalent to synchronized(this).
To be more precise:
For a class (static) method, the lock associated with the Class object for the method's class is used. For an instance method, the lock associated with this (the object for which the method was invoked) is used.
If you want to be more explicit about your locking, you could do something like this:
class A {
protected final Object mutex = new Object();
public void myOneMethod() {
synchronized (mutex) {
// ...
}
}
}
class B extends A {
public void myOtherMethod() {
synchronized (mutex) {
// ...
}
}
}
In fact, this pattern is recommended by Brian Goetz in Java Concurrency in Practice, section 4.2.1 "The Java monitor pattern". That way you know exactly where your monitor is coming from.
Yes. Java uses "monitors" to implement synchronization, and synchronized methods use the object instance they're called on as monitor, which is obviously the same in this case.
Note that this is NOT true for static methods! There, the class instance of (I think) the declaring class is used, which would not be the same one.
Yes you are correct
When one thread is executing a synchronized method for an object, all other threads that invoke synchronized methods for the same object block (suspend execution) until the first thread is done with the object. In this case the object is B
Just a small addition for people who might be interested in the future..
Additionally remember that locks in Java are reentrant. If they were not this code of yours would result in a deadlock since as you've indicated both operations require the same lock.
From the conceptual viewpoint, the mutex integrity of some inheritance scenarios would be broken if synchonized methods of class A would only protect A's data in the context of subclass B. After all, not all of A's data is required to be private.
Imagine that you want to slightly extend the functionality of one method of A while keeping the rest of A's functionality including mutex protection. If A were only protecting itself, you would end up having to override all of A's synchronized methods to lift the original synchronization mechanism to the new subclass. Not very attractive and also not very efficient.