For example:
static private DateFormat df = new SimpleDateFormat();
public static void format(final Date date) {
for (int i = 0; i < 10; i++)
new Thread(new Runnable() {
public void run() {
System.out.println(df.format(date));
}
});
}
The DateFormat
class is documented as not a synchronized class, but if we use just the format method, it can't change the status of the whole class?
Suppose it's declared private, how can one be sure that the code is thread safe?
What is the best way to fix this code?:
Using a different instance for every thread.
Using a synchronized block.
There is no rule that makes the code thread safe, the only thing you can do is make sure that your code will work no matter how many times is it being actively executed, each thread can be interrupted at any point, with each thread being in its own state/location, and this for each function (static or otherwise) that ...
The collection classes that are thread-safe in Java are Stack, Vector, Properties, Hashtable, etc.
Since String is immutable in Java, it's inherently thread-safe. 2) Read-only or final variables in Java are also thread-safe in Java. 3) Locking is one way of achieving thread-safety in Java. 4) Static variables if not synchronized properly become a major cause of thread-safety issues.
Since the ++ and -- operations are not atomic the class is not thread safe. Also, since count is static , modifying it from decrement which is a synchronized instance method is unsafe since it can be called on different instances and modify count concurrently that way.
Therefore, the DateFormat
class is not thread safe. The documentation specifically says:
Date formats are not synchronized. It is recommended to create separate format instances for each thread. If multiple threads access a format concurrently, it must be synchronized externally.
Declaring a field private
does not make your implementation thread-safe. private
merely says that outside classes can't see that field. Let's look at your method:
for (int i=0;i<10;i++)
new Thread(new Runnable(){
public void run(){
System.out.println(df.format(date));
}
});
The Runnable
objects that you create are anonymous classes. Anonymous classes are inner classes, which have access to private fields of their surrounding class. If it wasn't so, your program would not compile - they could not access the df
field.
But they can. So in fact you are having 10 threads that are all accessing your one DateFormat
object, referred to by df
. Since we already know that DateFormat
is not thread-safe, your program is not thread-safe.
df
inside it. You didn't give the class declaration so I don't know what its name is). They have references to the same instance of your class. If both of them call format
at the same time, both will be running DateFormat.format
using the same private df
. Thus, this is not going to be thread-safe.DateFormat
(so you have a new copy every time you call the method). Beware of anonymous classes, though! In your example, even if df
was a local field to the format
method, it would still not be thread-safe because all your threads would be accessing the same copy.As per the docs, it is stated that the format is not thread safe.
Synchronization
Date formats are not synchronized. It is recommended to create separate format instances for each thread. If multiple threads access a format concurrently, it must be synchronized externally.
Date format
How to read this ? If you don't have explicit guarantee that some method is thread safe(or its documented as unsafe) then you cannot make any assumptions about it being safe.
However, if you really wish to only use single method which might not be statefull, you can always create high concurrency environment and test for data integrity with and without synchronization.
I have had similar question to this, with Ciphers and RSA. The answer there shows one way how to test specific method of java SE class in general for this. Note however that implementation could change at any point, and by making your own implementation against implementation details rather then interface might cause some unpredictable issues in the future.
testing for data integrity
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With