I want to have a resettable object instance for a session within my program that is thread safe, an example of a session might be a logged in user session.
I am currently doing something like this;
public final class ObjectFactory {
private static volatile NativeObjectWrapper instance = null;
private Singleton() {}
public static NativeObjectWrapper getInstance() {
if (instance == null) {
synchronized(ObjectFactory.class) {
if (instance == null) {
instance = new NativeObjectWrapper(AuthData);
}
}
}
return instance;
}
public void reset() {
synchronized(ObjectFactory.class) {
instance = null;
}
}
}
I want to have the object created lazily, with the ability to reset it. Is the above approach threadsafe? if not is there a common pattern to solve this?
An example again would be that scoped object here has some inner data based on the user session and therefore should be a new instance per user session.
Is the above approach threadsafe?
No, it is not.
Say we have two threads - A and B.
A calls getInstance(), passes the instance==null check, and then there's a context switch to B, which calls reset(). After B finishes executing reset(), A gets the context again and returns instance, which is now null.
if not is there a common pattern to solve this?
I don't remember seening singletons with a reset method, so I'm not aware of any common patterns for this problem. However, the simplest solution would be to just remove the first if (instance == null) check in getInstance(). This would make your implementation thread safe, as instance is always checked and modified within a synchronized block. In this scenario, you could also remove the volatile modifier from instance since it is always accessed from within a synchronized block.
There are more complex solutions I can think of, but I'd use them only if real-world profiling showed that you're spending too much time blocked on that synchronized block. Note that the JVM has some sophisticated ways of avoiding using "real" locks to minimize blocking.
One trickier approach could be to read the instance field just once:
public static Singleton getInstance() {
Singleton toReturn = instance;
if (toReturn == null) {
synchronized(SingletonFactory.class) {
if (instance == null) {
instance = new Singleton();
toReturn = instance;
}
}
}
return toReturn ;
}
But this could result in returning an old "instance". For example a thread could execute Singleton toReturn = instance and get a valid instance, then lose the CPU. At this point, a 1000 other threads could create and reset 1000 other instances until the original thread gets a spin on the CPU again, at which point it returns an old instance value. It's up to you whether such a case is acceptable.
Is the above approach threadsafe?
The answer depends on what you think "thread safe" means. There is nothing in your reset() method to prevent a thread that previously called getInstance() from continuing to use the old instance.
Is that "thread safe?"
Generally speaking, "thread safe" means that the actions of one thread can never cause other threads to see shared data in an inconsistent or invalid state. But what "inconsistent" or "invalid" mean depends on the structure of the shared data (i.e., on the design of the application.)
Another way of looking at it: If somebody tells you that a class is "thread safe," then they're probably telling you that concurrent calls to the class's methods by multiple threads will not do anything that disagrees with the class documentation and, will not do anything that disagrees with how a reaonable programmer thinks the class should behave in cases where the documentation is not absolutely clear.
NOTE: That is a weaker definition of "thread safety" because it glosses over the fact that, using thread-safe components to build a system does not guarantee that the system itself will be thread-safe.
Does everybody who uses your class clearly understand that no thread in the program may ever call reset() while any reference to the old singleton still exists? If so, then I would call that a weak design because it is very far from being "junior-programmer-safe," but I would grudgingly admit that, from a strict, language-lawyerly point of view, you could call your ObjectFactory class "thread safe."
Related
This question already has answers here:
Double Checked Locking in Singleton
(4 answers)
Closed 3 years ago.
Below is the code snippet for thread safe design. Why are we checking for instance = null both before and inside the synchronized block? Isn't it sufficient to check for it outside?
// double locking is used to reduce the overhead of the synchronized method
public static ThreadSafeSingleton getInstanceDoubleLocking() {
if (instance == null) {
synchronized (ThreadSafeSingleton.class) {
if (instance == null) {
instance = new ThreadSafeSingleton();
}
}
}
return instance;
}
Its called Double check in Singleton pattern
Let's assume the First thread enters in the method check if the instance is null if it is, It will acquire the lock and start creating the object.
Assume that while the first thread is still creating the instance (maybe a heavy object), at the same Time another thread may enter the method it checks the instance is yet null because first thread is still creating the resource and has the lock , now first threads create the object releases the lock and second thread enters the synchronized block and check that the instance is now not null condition fails and it comes out of the method. Thus only on instance is present.
more details
https://www.java67.com/2015/09/thread-safe-singleton-in-java-using-double-checked-locking-pattern.html
Checking inside is sufficient, however, as the comment indicates; this method first checks in a racy manner if the instance is initialized, to avoid some synchronizations: if instance is witnessed to be not null outside, and if all threads obey the protocol that the only possible change is instance becoming non-null, then it it safe not to synchronize to return instance once it has been observed non-null.
Checking outside is not sufficient (let's say from thread A), because, even if instance is indeed null outside; it may have been initialized by another thread until the inside check is reached by A. Without the second check, instance may be created twice and ooops two singletons!
Effective Java by Joshua Block discusses this pattern as well as its variants.
It isn't sufficient to check only in the outside of the block, as it could be that the test passes but then another thread sets the value of instance before the synchronized block is reached. If that happened then you could potentially have the singleton newed twice by two different threads, then have two different parts of the runtime point at two different singleton objects.
The code as written is thread safe. It appears to be making a very small performance optimisation that would make sense if this method is called extremely frequently or if your runtime environment is on embedded hardware.
outer if (instance == null) is for performance and inner if (instance == null) is ensuring the singleton creation.
Suppose we dont have any if (instance == null) the our code become as below,
// double locking is used to reduce the overhead of the synchronized method
public static ThreadSafeSingleton getInstanceDoubleLocking() {
synchronized (ThreadSafeSingleton.class) {
// any number of thread can enter this block one by one and can create new instance
instance = new ThreadSafeSingleton();
}
return instance;
}
threads can enter one by one but only one thread can create object after that other threads can enter the block but can not create instance but unnecessary they are entering into syncronization block. So putting outer if condition prevent later threads to enter synchronization block.
public static ThreadSafeSingleton getInstanceDoubleLocking() {
synchronized (ThreadSafeSingleton.class) {
// threads can enter one by one but only one thread can create object after that other threads can enter the block but can not create instance but unnecessary they are entering into syncronization block. So putting outer if condition prevent later threads to enter synchronization block.
if (instance == null) {
instance = new ThreadSafeSingleton();
}
}
return instance;
}
Is there any functional difference between these two ways of implementing a Singleton?
public class MySingleton {
private static MySingleton instance;
public static MySingleton getInstance() {
if (instance == null) {
instance = new MySingleton();
}
return instance;
}
}
public class MySingleton {
private static final MySingleton instance = new MySingleton();
public static MySingleton getInstance() {
return instance;
}
}
Besides the fact that the first way would allow for some sort of clearInstance() method. Though you could just make instance not final in the second method.
Does the first method technically perform better because it is only initialized the first time it is needed instead of when the program starts?
The first one is lazy loading and the second is eager loading. Maybe your application never call the singleton, so if creating new instance of your singleton be heavy resource consuming action, then the lazy loading is better since it create new instance once needed.
The first method you use is not thread safe. I would consider it to be a bug.
The second method is simpler, thread safe, fast and, if you make sure the constructor won't throw silly exceptions, correct.
If you absolutely need more logic you can go with the first method, must make sure you protect it with a mutex. Something like:
public class MySingleton {
private static final Object mylock = new Object();
private static MySingleton instance;
public static MySingleton getInstance() {
synchronized(mylock) {
if (instance == null) {
instance = new MySingleton();
}
return instance;
}
}
}
Clearly the code is more complex, uses more memory, it's slower, you can't declare the variable as final...
Both methods will initialize the Singleton lazily. In Java, all variable initialization and static constructors are involved by the class loader when the class is used, not on the start of the code. If your code path never invokes getInstance the Singleton will never get initialized.
Personally, I avoid singletons, but when I use them is always with an immediate allocation on the variable declaration.
Correction
I ran a few experiments, and it turns out class initialization happened in parallel with the execution of the main thread. It didn't waited, as I believed it would. At least on a very simplified test scenario the initialization is eager, but asynchronous.
Is there any functional difference between these two ways of implementing a Singleton?
Yes. If you use an initializer in the variable declaration, then the instance is created when the class is initialized, even if the instance is never accessed. If you initialize it in the getInstance() method then the instance is only created if it is accessed. That has thread safety implications. It does does not otherwise make much difference if initializing an instance is cheap and without lasting external side effects, but that may not always be the case.
Does the first method technically perform better because it is only
initialized the first time it is needed instead of when the program
starts?
If you are going to use an instance in any case then you are going to pay the cost of initializing it at some point no matter what, so there is no performance difference in that sense. However, a thread-safe version of the first method will be slightly more expensive than the second method on the first invocation, and you will pay that extra overhead again on every subsequent invocation.
Its about Lazy Initialization vs Eager initialization. The difference is, in the first one the instance will not create until you call the getInstance() method, but in the second one its already have been created even before you call the getInstance() method.
Please refer this link if you want more info
From the unit testing point of view I prefer the lazy instatiatiation. Given that the singleton's initialization has further side effects (which are irrelevant to the actual test), and you want to test a class which needs the singleton (maybe just one particular method), it's easier to mock the singleton and inject it to the instance variable while preparing the test. Using a mock for your singleton instance you have easier control what the singleton's method return to your class under test.
The overhead of the thread safe instantiation can be minimized by the double checked lock pattern:
private static volatile MySingleton instance;
public static MySingleton getInstance() {
if (instance == null) {
synchronized ( MySingleton.class ) {
if (instance == null) {
instance = new MySingleton();
}
}
}
return instance;
}
Thus only the rare situation where two (or more) threads access the singleton for the first time (and at the same time) may enter the lock state. Afterwards the first ''if null'' will return false and you never enter the lock state again.
Important: the member has to be declared volatile for this pattern to work reliably.
Note: It has been proven that the above "double checked lock" pattern is not 100 percent reliable. See the discussion below in the comments and especially Brian Goetz' arcticle
I am learning Java concurrency and know that the following singleton is not completely thread safe. A thread may get instance before it is initialized because of instructions reordering. A correct way to prevent this potential problem is to use volatile keyword.
public class DoubleCheckedLocking {
private static Instance instance;
public static Instance getInstance() {
if (instance == null) {
synchronized (DoubleCheckedLocking.class) {
if (instance == null)
instance = new Instance();
}
}
return instance;
}
}
I tried to reproduce the potential problem without volatile keyword and wrote a demo to show that using the above code may cause a NullPointerException in multithreading environment. But I failed to find a way to explicitly let the Java compiler perform instructions reordering and my demo with the above singleton always works pretty well without any problems.
So my question is how to explicitly enable/disable Java compiler to reorder instructions or how to reproduce the problem without using volatile keyword in a double-checked locking singleton?
The dangerous thing here is not necessarily, that other threads may receive null as an answer from getInstance. The dangerous thing is, that they may observe an instance, which is not (yet) properly initialized.
To check this, add a few fields to your singleton, say:
class Singleton {
private List<Object> members;
private Singleton() {
members = new ArrayList<>();
members.addAll(queryMembers());
}
private Collection<Object> queryMembers() {
return Arrays.asList("Hello", 1, 2L, "world", new Object());
}
public int size() {
return members.size();
}
private static Singleton instance = null;
public static Singleton getInstance() {
if (instance == null) {
synchronized (DoubleCheckedLocking.class) {
if (instance == null)
instance = new Singleton();
}
}
return instance;
}
}
This is called "unsafe publication". Other threads may see the singleton instance partially initialized (i.e., the members field may still be null, or the list may be empty, or only partially filled, or worse: in an inconsistent state due to an object just being added).
In the example code above, no external caller of size should ever see a value different from 5, right? I didn't try it, but I wouldn't be surprised, if callers can observe different values, if the timing isn't right.
The reason for this is, that the compiler is allowed to translate
instance = new Singleton();
into something along the lines of
instance = allocate_instance(Singleton.class); // pseudo-code
instance.<init>();
and thus, we have a window, in which instance is no longer null, but the actual object is not yet properly initialized.
The "Double-Checked Locking is Broken" Declaration gives an in-depth explanation of this.
This is an excerpt from the Java Concurrency in Practice book:
Debugging tip: For server applications, be sure to always specify the
-server JVM command line switch when invoking the JVM, even for development and testing. The server JVM performs more optimization
than the client JVM, such as hoisting variables out of a loop that are
not modified in the loop; code that might appear to work in the
development environment (client JVM) can break in the deployment
environment (server JVM). For example, had we "forgotten" to declare
the variable asleep as volatile in Listing 3.4, the server JVM could
hoist the test out of the loop (turning it into an infinite loop), but
the client JVM would not. An infinite loop that shows up in
development is far less costly than one that only shows up in
production.
So you can give it a try. But there is no 100% sure way of enabling reordering.
I want to know how to use synchronized blocks across classes. What I mean is, I want to have synchronized blocks in more than one class but they're all synchronizing on the same object. The only way that I've thought of how to do this is like this:
//class 1
public static Object obj = new Object();
someMethod(){
synchronized(obj){
//code
}
}
//class 2
someMethod(){
synchronized(firstClass.obj){
//code
}
}
In this example I created an arbitrary Object to synchronize on in the first class, and in the second class also synchronized on it by statically referring to it. However, this seems like bad coding to me.
Is there a better way to achieve this?
Having a static object that is used as a lock typically is not desirable because only one thread at a time in the whole application can make progress. When you have multiple classes all sharing the same lock that's even worse, you can end up with a program that has little to no actual concurrency.
The reason Java has intrinsic locks on every object is so that objects can use synchronization to protect their own data. Threads call methods on the object, if the object needs to be protected from concurrent changes then you can add the synchronized keyword to the object's methods so that each calling thread must acquire the lock on that object before it can execute a method on it. That way calls to unrelated objects don't require the same lock and you have a better chance of having code actually run concurrently.
Locking shouldn't necessarily be your first go-to technique for concurrency. Actually there are a number of techniques you can use. In order of descending preference:
1) eliminate mutable state wherever possible; immutable objects and stateless functions are ideal because there's no state to protect and no locking required.
2) use thread-confinement where you can; if you can limit state to a single thread then you can avoid data races and memory visibility issues, and minimize the amount of locking.
3) use concurrency libraries and frameworks in preference to rolling your own objects with locking. Get acquainted with the classes in java.util.concurrent. These are a lot better written than anything an application developer can manage to throw together.
Once you've done as much as you can with 1, 2, and 3 above, then you can think about using locking (where locking includes options like ReentrantLock as well as intrinsic locking). Associating the lock with the object being protected minimizes the scope of the lock so that a thread doesn't hold the lock longer than it needs to.
Also if the locks aren't on the data being locked then if at some point you decide to use different locks rather than having everything lock on the same thing, then avoiding deadlocks may be challenging. Locking on the data structures that need protecting makes the locking behavior easier to reason about.
Advice to avoid intrinsic locks altogether may be premature optimization. First make sure you're locking on the right things no more than necessary.
OPTION 1:
More simple way would be to create a separate object (singleton) using enum or static inner class. Then use it to lock in both the classes, it looks elegant:
// use any singleton object, at it's simplest can use any unique string in double quotes
public enum LockObj {
INSTANCE;
}
public class Class1 {
public void someMethod() {
synchronized (LockObj.INSTANCE) {
// some code
}
}
}
public class Class2 {
public void someMethod() {
synchronized (LockObj.INSTANCE) {
// some code
}
}
}
OPTION:2
you can use any string as JVM makes sure it's only present once per JVM. Uniqueness is to make sure no-other lock is present on this string. Don't use this option at all, this is just to clarify the concept.
public class Class1 {
public void someMethod() {
synchronized ("MyUniqueString") {
// some code
}
}
}
public class Class2 {
public void someMethod() {
synchronized ("MyUniqueString") {
// some code
}
}
}
Your code seems valid to me, even if it does not look that nice. But please make your Object you are synchronizing on final.
However there could be some considerations depending on your actual context.
In any way should clearly state out in the Javadocs what you want to archive.
Another approach is to sync on FirstClass e.g.
synchronized (FirstClass.class) {
// do what you have to do
}
However every synchronized method in FirstClass is identical to the synchronized block above. With other words, they are also synchronized on the same object. - Depending on the context it may be better.
Under other circumstances, maybe you'd like to prefer some BlockingQueue implementation if it comes down that you want to synchronize on db access or similar.
I think what you want to do is this. You have two worker classes that perform some operations on the same context object. Then you want to lock both of the worker classes on the context object.Then the following code will work for you.
public class Worker1 {
private final Context context;
public Worker1(Context context) {
this.context = context;
}
public void someMethod(){
synchronized (this.context){
// do your work here
}
}
}
public class Worker2 {
private final Context context;
public Worker2(Context context) {
this.context = context;
}
public void someMethod(){
synchronized (this.context){
// do your work here
}
}
}
public class Context {
public static void main(String[] args) {
Context context = new Context();
Worker1 worker1 = new Worker1(context);
Worker2 worker2 = new Worker2(context);
worker1.someMethod();
worker2.someMethod();
}
}
I think you are going the wrong way, using synchronized blocks at all. Since Java 1.5 there is the package java.util.concurrent which gives you high level control over synchronization issues.
There is for example the Semaphore class, which provides does some base work where you need only simple synchronization:
Semaphore s = new Semaphore(1);
s.acquire();
try {
// critical section
} finally {
s.release();
}
even this simple class gives you a lot more than synchronized, for example the possibility of a tryAcquire() which will immediately return whether or not a lock was obtained and leaves to you the option to do non-critical work until the lock becomes available.
Using these classes also makes it clearer, what prupose your objects have. While a generic monitor object might be misunderstood, a Semaphore is by default something associated with threading.
If you peek further into the concurrent-package, you will find more specific synchronisation-classes like the ReentrantReadWriteLock which allows to define, that there might be many concurrent read-operations, while only write-ops are actually synchronized against other read/writes. You will find a Phaser which allows you to synchronize threads such that specific tasks will be performed synchronously (sort of the opposite of synchornized) and also lots of data structures which might make synchronization unnecessary at all in certain situations.
All-in-all: Don't use plain synchronized at all unless you know exactly why or you are stuck with Java 1.4. It is hard to read and understand and most probably you are implementing at least parts of the higher functions of Semaphore or Lock.
For your scenario, I can suggest you to write a Helper class which returns the monitor object via specific method. Method name itself define the logical name of the lock object which helps your code readability.
public class LockingSupport {
private static final LockingSupport INSTANCE = new LockingSupport();
private Object printLock = new Object();
// you may have different lock
private Object galaxyLock = new Object();
public static LockingSupport get() {
return INSTANCE;
}
public Object getPrintLock() {
return printLock;
}
public Object getGalaxyLock() {
return galaxyLock;
}
}
In your methods where you want to enforce the synchronization, you may ask the support to return the appropriate lock object as shown below.
public static void unsafeOperation() {
Object lock = LockingSupport.get().getPrintLock();
synchronized (lock) {
// perform your operation
}
}
public void unsafeOperation2() { //notice static modifier does not matter
Object lock = LockingSupport.get().getPrintLock();
synchronized (lock) {
// perform your operation
}
}
Below are few advantages:
By having this approach, you may use the method references to find all places where the shared lock is being used.
You may write the advanced logic to return the different lock object(e.g. based on caller's class package to return same lock object for all classes of one package but different lock object for classes of other package etc.)
You can gradually upgrade the Lock implementation to use java.util.concurrent.locks.LockAPIs. as shown below
e.g. (changing lock object type will not break existing code, thought it is not good idea to use Lock object as synchronized( lock) )
public static void unsafeOperation2() {
Lock lock = LockingSupport.get().getGalaxyLock();
lock.lock();
try {
// perform your operation
} finally {
lock.unlock();
}
}
Hopes it helps.
First of all, here are the issues with your current approach:
The lock object is not called lock or similar. (Yes ... a nitpick)
The variable is not final. If something accidentally (or deliberately) changes obj, your synchronization will break.
The variable is public. That means other code could cause problems by acquiring the lock.
I imagine that some of these effects are at the root of your critique: "this seems like bad coding to me".
To my mind, there are two fundamental problems here:
You have a leaky abstraction. Publishing the lock object outside of "class 1" in any way (as a public or package private variable OR via a getter) is exposing the locking mechanism. That should be avoided.
Using a single "global" lock means that you have a concurrency bottleneck.
The first problem can be addressed by abstracting out the locking. For example:
someMethod() {
Class1.doWithLock(() -> { /* code */ });
}
where doWithLock() is a static method that takes a Runnable or Callable or similar, and then runs it with an appropriate lock. The implementation of doWithLock() can use its own private static final Object lock ... or some other locking mechanism according to its specification.
The second problem is harder. Getting rid of a "global lock" typically requires either a re-think of the application architecture, or changing to a different data structures that don't require an external lock.
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.