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.
Related
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.
I have a Util class with a utility methods as:
public static String formatAmount(String amount) throws Exception {
return String.format("%,.2f", Double.valueOf(amount));
}
Is this method thread safe? I am not modifying amount any where else.
Secondly, I have another method as.
private boolean checkIfDateIsAHoliday(org.joda.time.LocalDate date) {
boolean isHoliday = false;
.......
return isHoliday;
}
Is this method thread safe? I am not modifying date any where else.
As always the hell is in the small details. Your first method is thread safe because it definitely does not change state of any class.
Your seconds method is available only partially. I do not know what is written in your code instead of ........ If you do not change state your any class there the method is thread-safe, otherwise it is not.
Thread safety is all about accessing shared state. So if you want to know if a method is thread safe, you only have to check if it accesses state (=fields) that can also be accessed by other threads:
If there is no such state, you're done - the method is thread safe.
If there is such state, you have to check if it is accessed in a thread safe manner.
(See also http://tutorials.jenkov.com/java-concurrency/thread-safety.html)
Your first method does not access any shared state (String is immutable, hence the parameter is thread-safe by itself). It calls two static methods (String.format and Double.valueOf) which might access shared state. Unfortunately, javadoc does not say anything concerning thread-safety of these two methods. Nevertheless we can assume that they are (otherwise almost all java applications were broken).
Your second method is thread safe concerning the code we can see (we can't argue about the code behind .....). Reason: You're just modifying local state (stack variable isHoliday). As local state cannot be accessed by other threads, this is thread-safe by definition.
Now just try to argue concerning the rest of your code (.....)!
For the First method it will be Thread safe But
It won't be Thread Safe for the method you have declared in the second
The first one is thread-safe because you are only reading an immutable variable String.
Joda's LocalDate is also immutable. Therefore, assuming you are not reading or writing mutable class or instance fields, this method is also threadsafe.
I am aware of locking concepts with synchronization of static and non static methods to lock classes and instances respectively. What I am not able to understand is, how is class level lock achieved? I mean, class is a template only, with no physical significance. So, when we say that class level locking is achieved with synchronizing static methods what happens then? Do all the objects of that class get locked or some other process?
With what I could find out with my search is that there are class objects (Class.class) and lock is acquired on this class object. But then how are all instances of that class also locked?
Do all the objects of that class get locked or some other process?
First, let's talk about what what it means to "lock" an object.
Foobar foobar = new Foobar();
synchronized (foobar) {
...
}
You might say that the foobar object is "locked" when a thread is in the synchronized block. But what does that do for the program? A lot of newbies make the mistake of thinking that it will prevent other threads from accessing the object. But, that is not true. What synchronized does--the only thing synchronized does--is to guarantee that no more than one thread can be synchronized on the same object at the same time.
The programmer's intent in the example above might be to prevent other threads from seeing foobar in an inconsistent state. In that case, every method and every fragment of code that accesses foobar must be synchronized on foobar. Imagine foobar as big room with many doors. Each method that uses foobar is like a different door. If you want to keep people out of the room, it doesn't help to lock just one door. You have to lock all of them.
So now, to your question:
when we say that class level locking is achieved with synchronizing static methods what happens then?
Simple. This:
class Foobar {
static synchonized void do_something() {
...
}
}
Does exactly the same as this:
class Foobar {
static void do_something() {
synchronized(Foobar.class) {
...
}
}
}
You always synchronize on an Object. Well, a class is an Object. When a static method is synchronized, that just means that the method body is synchronized on the class object.
Since a class is a singleton object, that means that no two threads can get into the same static synchronized method at the same time. In my earlier example, the variable foobar could refer to different objects at different times, but in the static example, Foobar.class is guaranteed always to refer to the same singleton.
Edit: As, #Danny pointed out, there is no connection between a block that is synchronized on the Foobar class, (my second example) and a block that is synchronized on an instance of the Foobar class (my first example). The instance and the class object are two different objects, so nothing prevents one thread from synchronizing on the instance while another thread is synchronized on the class. Likewise, nothing prevents two different threads from synchronizing on two different instances. Another mistake that newbies often make is to think that only one thread at a time can enter this synchronized block:
Integer n = ...;
synchronized (n) {
n = n+1;
...
}
But it's not true. It's not the variable, n, that is locked, it's a particular instance of the Integer class. Each thread that enters the block creates a new Integer instance and assigns it to n. So when the next thread comes along, n no longer refers to the same instance that the first thread has synchronized.
Class Shared{
public void sharedMethod(Object o){
//does something to Object
}
}
//this is how threads call the shared method
run(){
sharedInstance.sharedMethod(someObject);
}
Now the o is being passed as the parameter to the method. And the same method is being called by multiple threads in parallel. Can we safely say that this code is thread safe?
There are two scenarios:
If the someObject is being shared among the threads
If every Thread has its own copy of someObject
No you cannot say that. Method parameters are local to threads, meaning each one has their own copy of the o reference variable, But if you call this method with the same object from multiple threads, then the argument will be shared between them (remember that Java is pass-by-value). In that case, you need to provide explicit synchronization to avoid troubles.
Yes, but only in two scenarios:
if every object you pass in the o parameter is immutable,
if your code guarantees that there is at most one thread working on the object referenced by o.
Otherwise - no, since the internal state of the object can be changed by multiple threads concurrently.
When you create a thread it will have its own stack created (method and local variables).
Two threads will have two stacks and one thread never shares its stack with any other thread.
It will not effect until you are calling this on same object.
If you call the same method in multiple threads, and pass it the same object, that object is absolutely not safe.
Treat it this way.
If your threads don't share any common resources, than it's impossible to have concurrency problems.
As much as we can tell from the information you provided, the only thing that can be shared here, is someObject. If it's thread-safe itself, or being copied for each thread, than your code is thread safe in general, unless there are other shared resources.
Local variables are stored in each thread's own stack. That means that local variables are never shared between threads. That also means that all local primitive variables are thread safe.
EDIT
The LocalObject instance in this example is not returned from the method, nor is it passed to any other objects that are accessible from outside the sharedMethod() method.
Each thread executing the sharedMethod() method will make use of its own Object o as parameter.
So, the whole method sharedMethod() seems to be thread safe.
The only exception is of course, if one of the methods called with the Object o as parameter, stores the Object o instance in a way that allows access to it from other threads.
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.