Thursday, 28 July 2011

Multithreading- Understanding thread Safety in Java

Thread Save : Code that is safe to call by multiple threads simultanously is called thread safe.


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. Here is an example of a thread safe local primitive variable:

public void someMethod(){
      long threadSafeInt = 0;
      threadSafeInt++;
}

Local Object References All objects are stored in the shared heap. If an object created locally never escapes the method it was created in, it is thread safe. In fact you can also pass it on to other methods and objects as long as none of these methods or objects make the passed object available to other threads.
Thread safe local object:

public void someMethod(){

      LocalObject localObject = new LocalObject();
      localObject.callMethod();
      method2(localObject);
}
public void method2(LocalObject localObject){
      localObject.setValue("value");
}
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 someMethod() method. Each thread executing the someMethod() method will create its own LocalObject instance and assign it to the localObject reference. Therefore the use of the LocalObject here is thread safe. In fact, the whole method someMethod() is thread safe. Even if the LocalObject instance is passed as parameter to other methods in the same class, or in other classes, the use of it is thread safe. The only exception is of course, if one of the methods called with the LocalObject as parameter, stores the LocalObject instance in a way that allows access to it from other threads


Object Members: Object members are stored on the heap along with the object. Therefore, if two threads call a method on the same object instance and this method updates object members, the method is not thread safe. Here is an example of a method that is not thread safe:

public class NotThreadSafe{

     StringBuilder builder = new StringBuilder();
     public add(String text){
     this.builder.append(text);
     }
}
Even if the use of an object is thread safe, if that object points to a shared resource like a file or database, your application as a whole may not be thread safe. For instance, if thread 1 and thread 2 each create their own database connections, connection 1 and connection 2, the use of each connection itself is thread safe. But the use of the database the connections point to may not be thread safe. For example, if both threads execute code like this:
check if record X exists
if not, insert record X

If two threads execute this simultanously, and the record X they are checking for happens to be the same record, there is a risk that both of the threads end up inserting it. This is how:

Thread 1 checks if record X exists. Result = no
Thread 2 checks if record X exists. Result = no
Thread 1 inserts record X
Thread 2 inserts record X

This could also happen with threads operating on files or other shared resources. Therefore it is important to distinguish between whether an object controlled by a thread is the resource, or if it merely references the resource.

Immutable objects are thread safe. But the reference to immutable object may not be thread safe. i.e the class with has immutable object as its member may not be thread safe itself.














No comments:

Post a Comment