how to know if java SE class or method is thread safe?

For example having :

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));
         } 
     });
}

DateFormat class it documented as not synchornized Class, but if we use just the format Method, it can't change the statut of the hole Class?

Suppose it is declared private, how to be sure that this code is thread safe ?

What is the best way to fix this code ?:

   1_ Using a different instance for every Thread.
   2_ Using a synchronized block.

Answers


  • For a standard Java SE class, the best way to know whether or not the class is thread-safe is to carefully read its documentation. Always read both the class documentation and the method documentation. If either say it's not synchronized or not thread-safe, you know it's not thread-safe.
  • 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.

  • Furthermore, if two external threads have references to your object (I mean the object that has the 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.
  • To be thread-safe, you need to synchronize on the object or use some other kind of lock (one lock for all the possible threads that access it), which is exactly what the documentation said to do.
  • Another way is to have a completely local object, which is visible to only one thread. Not a field - a local variable, which has access to a uniquely created instance of 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.

Need Your Help

Performs logout when user remove app via task swipe in android

android android-service swipe logout

I want to clear user credentials and log user out when the user user removes the app from current running app list. Here, what I'm doing, is that when user ends the app by swiping off the app list...

How can I pass an argument by reference when I use __call

php design-patterns decorator magic-methods

As I am working on a piece of code that needs the decorator pattern, I wanted to make it really simple to use by handling the __call magic method.

About UNIX Resources Network

Original, collect and organize Developers related documents, information and materials, contains jQuery, Html, CSS, MySQL, .NET, ASP.NET, SQL, objective-c, iPhone, Ruby on Rails, C, SQL Server, Ruby, Arrays, Regex, ASP.NET MVC, WPF, XML, Ajax, DataBase, and so on.