Sunday, February 22, 2009

ThreadLocal & InheritableThreadLocal in Java, initialValue() v/s set(), Uses of childValue()


ThreadLocal in Java - what is it used for?

As the name suggests this Java library class is used for supporting thread-local variables - the variables which are local to the particular thread instance and hence each thread will have their own copy of such variables which will be initialized every time a new thread is spawned.


To be more clear, let's take one simple example. If you have a class having some private/public static fields defined in it then all the objects created in all threads will share the same instances of those static fields. What if you want every thread to have a separate copy of it? ThreadLocal class will be of use in such cases, in fact they are mainly used for this purpose only. You can't just switch to a non-static field as in that case all the objects (even those created in the same thread) will have their own copies. You may come across situations asking you to have copies based on threads and not based on instances. This is where you will probably like to use ThreadLocal.


This class was introduced to Java in the version 1.2 and it has only three methods - one protected (initialValue()) and two public (get() and set()). The method set() is only rarely used as for most of the applications use the initialValue() method does the trick.

  • protected Object initialValue() - as the name suggests this method returns the initial value of the ThreadLocal variable for the current thread and it's invoked at most once per thread. This method will be executed only if the thread calls the get() method on the ThreadLocal variable for the time and also only if the thread doesn't call set() method on the ThreadLocal variable prior to calling get() on it. As already mentioned that initialValue() method is called only when get() is called for the first time and hence if the thread calls set() method before get() then the initialValue() will never be executed on that ThreadLocal variable.
  • public Object get() - evidently it will return the value of the ThreadLocal variable for the current thread. As discussed above, if it's called for the first time then the ThreadLocal variable is created and initialized by calling the initialValue() method internally.
  • public void set(Object value) - like any other setter this method will also set the current thread's copy of the ThreadLocal variable to the passed 'value'. This method is used only rarely as in most of the cases initialValue() method solves the purpose in a better way.

initialValue() method v/s set() method for a ThreadLocal variable


  • initialValue() method is called at most once and it's called only implicitly whereas set() method can be called any number of times and every time the call will be an explicit call.
  • initialValue() is called when get() method is called for the first time on the ThreadLocal variable in the current thread and that too only when set() method has not been called before the first get() call (in which case initialValue() method is never called in that thread on that ThreadLocal variable).

Overriding the initialValue() method and using it in an application

initialValue() method is a protected method which initializes the ThreadLocal variable with 'null' in its default implementation and almost every time we need to override this method to initialize the ThreadLocal variable as per our requirements. Anonymous inner classes are normally used for this overriding to make the code more readable and maintainable. Let's walk through the sample code given in the Sun Javadoc for ThreadLocal.



public class SerialNum {
// The next serial number to be assigned
private static int nextSerialNum = 0;

private static ThreadLocal serialNum = new ThreadLocal() {
protected synchronized Object initialValue() {
return new Integer(nextSerialNum++);
}
};

public static int get() {
return ((Integer) (serialNum.get())).intValue();
}
}


In the above example, changes made to the private static int field named 'nextSerialNum' will be reflected in all the threads using the 'SerialNum' class as it's a normal static field and will be shared across all the instances created in all the threads, but the static ThreadLocal field named 'serialNum' will be created and maintained separately for all the threads and will not be shared across all the threads.


As you can see that anonymous inner class has been used to override the initialValue() method which sets the initial value of the ThreadLocal variable 'serialNum' to the Integer object created with the current value of the static field 'nextSerialNum'.


A call to the get method of the 'SerialNum' class will ultimately call the get() method on the ThreadLocal variable 'serialNum' and if the first outer get (of the SerialNum class) call will obviously make the first inner get (of the ThreadLocal class) call on the ThreadLocal instance 'serialNum' which will subsequently invoke the initialValue() on the ThreadLocal variable in the current thread.


InheritableThreadLocal - what's this and when to use it?


Suppose you have a requirement of setting the value of a ThreadLocal variable in a child thread as a function of the value of a ThreadLocal variable in the parent thread, then using a normal ThreadLocal variable won't do the needful as for ThreadLocal variables the initial values are set independently in every thread including any child threads as well.


InheritableThreadLocal which subclasses ThreadLocal class is used in such situations. This class has only one method 'protected Object childValue(Object parentValue)' which is used to set the initial value of the InheritableThreadLocal variable in the child thread as a function of a ThreadLocal variable (passed as a parameter) in the parent thread. This method is called from within the parent thread before the child thread is created and the default implementation will make the child values identical to parent's, but we can override the childValue() method to set the child value as a function of the parent value for those ThreadLocals which have values in the parent thread. By default the childValue() returns the same input argument, but again an override of the childValue method might change this behavior as well.


Liked the article? Subscribe to this blog for regular updates. You may also like to follow the blog to manage the bookmark easily and to tell the world that you enjoy GeekExplains. Interested? Find the 'Followers' widget in the rightmost sidebar.



Share/Save/Bookmark


Monday, February 16, 2009

LoadLibrary failed - a DLL initialization routine failed


Resolving 'LoadLibrary failed - a DLL initialization routine failed' error

LoadLibrary failed - a DLL initialization routine failed
There might be other reasons for this error as well, but the most common one is probably because of a missing dependent DLL. While trying to register SOAPIS30.dll (for those who are new to DLL installation - that's done by using RegSvr32.exe OR Gacutil.exe), I encountered this error.

Identifying the problem and fixing that - using Dependency Walker

As we commonly do with other DLL registration errors, I started with analyzing the DLL and trying to register it from within Dependency Walker tool. While trying to register, it straightaway gave me three errors, all indicating the same missing dependent DLL. It actually tried to look for this DLL in three directories and hence three errors for the same missing DLL.



LoadLibraryExA("C:\Program Files\Common Files\MSSoap\Binaries\Resources\2057\MSSOAPR3.DLL", 0x00000000, LOAD_WITH_ALTERED_SEARCH_PATH) returned NULL. Error: The specified module could not be found (126).

LoadLibraryExA("C:\Program Files\Common Files\MSSoap\Binaries\Resources\1033\MSSOAPR3.DLL", 0x00000000, LOAD_WITH_ALTERED_SEARCH_PATH) returned NULL. Error: The specified module could not be found (126).

LoadLibraryExA("C:\Program Files\Common Files\MSSoap\Binaries\MSSOAPR3.DLL", 0x00000000, LOAD_WITH_ALTERED_SEARCH_PATH) returned NULL. Error: The specified module could not be found (126).


How to register DLLs from within Dependency Walker?

Open the RegSvr32.exe (found in WINDOWS\System32 folder) in DW and then run the profiler by selecting the corresponding main-menu option. It will prompt you to browse and enter the particular DLL, which you want to install.


If you have corrected the error i.e., in this case if you have placed the missing DLL in any of the three directories where it is expected to be (you can easily identify the directories in the DW error messages pasted above) and assuming that everything else is fine, like the DLL is not a corrupted one, etc. then you would see the below alert showing that the registration of the DLL has completed successfully.


DLL registered successfully
This alert marks the end of a successful DLL registration as is quite evident from the message displayed in the alert box.

Liked the article? Subscribe to this blog for regular updates. You may like to follow the blog to manage the bookmark easily and to tell the world that you enjoy GeekExplains. Interested? Find the 'Followers' widget in the rightmost sidebar.



Share/Save/Bookmark