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.
Related
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."
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.
Say I have an object A which has 2 methods:
public doSomething()
{....}
public synchronised doSomethingElse()
{ ... }
and I have thread1.doSomethingElse(), will it still be possible for thread2.doSomething() to execute or is it blocked by thread1's lock?
If so, how can I make thread1 execute at the same time?
There are two types of synchronization
1. Object level
2. Class level (Class level synchronization is for the static methods only.)
In your case since your methods are not static it is object level synchronization. For object level synchronization you can either synchronize your whole methods or you can synchronize some block of your methods.
When you synchronized one method. Its mean that same object of your class cant access your synchronized method from different threads. As each object have only one lock. If you had called doSomethingElse() for same obj but from different threads. Then It will be accessible by one thread.
Now comes to your answer:
As your first method is not synchronized i.e something(). It will not be effected in any case if you call it for any no of threads or even call it when your first thread is currently in the method. Locks are only for synchronized methods
Yourclass obj = new Yourclass();
Thread A = new MyThread(obj);
Thread B = new MyThread(obj);
......
public void run()
{
\\do what ever you want
\\both of your methods will be called.
\\ call them both here.
}
here i have made objects of same Mythread class you can do as per you want. you can make objects of two different implemented thread classes and write your run. In any case it will have no effect on the call.
Since thread 2 is not attempting to acquire any lock, it is not blocked and can run concurrently with thread 1. There's nothing special you need to do.
I'm new to Java, so pls excuse if answer to below simple case is obvious.
class A{
public void foo(Customer cust){
cust.setName(cust.getFirstName() + " " + cust.getLastName());
cust.setAddress(new Address("Rome"));
}
}
I've a Singleton object (objectA) created for class A.
Given I don't have any class variable, is it thread safe if I call objectA.foo(new Customer()) from different threads?
What if I change foo to static and call A.foo(new Customer()) from different threads?
is it still thread safe?
Given I don't have any class variable, is it thread safe if I call
objectA.foo(new Customer()) from different threads?
Of course it is. Your foo() method doesn't change any state of the A object (since it doesn't have any) and the object you pass, new Customer(), as an argument to the method is not available to any other thread.
What if I change foo to static and call A.foo(new Customer()) from
different threads? is it still thread safe?
As long as you don't have any mutable static state, you're still good.
Yes, it will be thread-safe IF you call foo(new Customer()) from different threads. But this is only because each time you call new Customer() you are making a new (and therefore different) Customer object, and all that foo does is alter the state of the Customer that is passed to it. Thus these threads will not collide, because even though they are calling the same method, they will be manipulating different customers.
However, if you were to create a customer variable first
Customer bob = new Customer()
and then call foo(bob) from two different threads, it would not be thread safe. The first thread could be changing the address while the second thread is changing the name, causing inconsistent behavior and / or corrupt data.
If you want to make this method truly thread-safe, just declare the method synchronized:
public synchronized void foo(Customer cust) {...}
thread safety is required where a function is accessing a static shared variable. like a function which is updating a shared document, so if two thread in parallel updated changes of one thread will get ignore. Or a static variable which is shared across the application, singleton object.
Above are some situation where thread safety required In your case you are not updating any shared resource so this is a thread safe.
I i make a call to noonsynchronized method from within my synchronized method is it thread safe?
I have 2 methods as follows:
public class MyClass{
void synchronized doSomething1(){
doSomething2();
}
void doSomething2(){
//will this block of code be synchronized if called only from doSomething1??
}
}
If doSomething2() is only called from doSomething1(), then it will only be called by a single thread for a single instance of MyClass. It could still be called from different threads at the same time, via different instances - so if it acts on any shared data which may not be specific to the instance of MyClass, it's still not guaranteed to fix all threading issues.
Basically, you need to think carefully about any mutable shared state used by multiple threads - there are no easy fixes to that, if you need mutable shared state. In your particular case you'd also need to make sure that doSomething2() was only called from doSomething1() - which would mean making it private to start with...
When calling doSomething1() the caller's Thread locks on the monitor of the instance of MyClass. Until that thread's execution exits doSomething1 the lock will remain which includes if it goes into doSomething2. This will cause other threads to block when attempting to lock.
Keep in mind:
synchronized does not thread-safe it make.
Further info:
JLS 3rd Ed 17.1 Locks
If doSomething2() is called ONLY from doSomething1() then yes - it is thread safe.