Best use of ThreadLocal class to handle Selenium Session
Posted: August 12th, 2009 | Author: Anuradha Uduwage | Filed under: Java Ruled, Selenium | Tags: Java, Selenium | No Comments »Dealing with threads in Java is not the easiest but I was in the process of implementing a custom Java Selenium Framework and I decided “Why not use the help of the ThreadLocal class to ease my pain”. So, this is my attempt to take stab at ThreadLocal class.
Why Did I need to use the ThreadLocal class?
Only thing you need to know about my implementation.
As I mentioned, I have created class that extends DefualtSelenium.java (lets call it OurDefaultSelenium.java, this class has method that start the selenium session)
So, just because I think I should use the ThreadLocal class does it mean is it the best mechanism to use..?
Most typical scenario of using ThreadLocal would be as an alternative to an object or resource pool, when we don’t mind creating one object per thread.
So When should I really use the Thread Local
Ok enough of lecturing, lets get to the bottom of it, shall we.
- Lets call our Class, SeleniumSession make sense right we are dealing with selenium session.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | public class SeleniumSession { private static final Logger log = Logger.getLogger(SeleniumSession.class.getName()); private static ThreadLocal<HashMap<String, OurDefaultSelenium>> session= new ThreadLocal<HashMap<String, OurDefaultSelenium >>() { protected synchronized HashMap<String, OurDefaultSelenium > initialvalue() { return new HashMap<String, OurDefaultSelenium >(); } }; private static ThreadLocal< OurDefaultSelenium > selenium = new ThreadLocal< OurDefaultSelenium>(); /** * Get the current selenium session. * @return */ public static OurDefaultSelenium get() { return selenium.get(); } |
-
Note that there is still a single, static instance of SeleniumSession shared by all threads. But that single instance uses the ThreadLocal variable session, which has a per-thread value. Inside get(), the call to selenium.get() will always operate on our thread-private “instance” of the variable, with synchronization.
Since we are using Java generics, subsequent get() method doesn’t need an explicit cast. (That is, the cast is inserted automatically by the compiler.)
But lets focus our eyes on to
1 | <strong>initialValue </strong> |
method. We actually subclass ThreadLocal and override
1 | initialValue() |
to provide an appropriate object each time a new one is required (i.e. when
1 | get() |
is called for the first time on a particular thread). I know what you thinking, You could add a logic to check the null inside the
1 | get() |
method. Like this,
OurDefaultSelenium ourSelenium = session.get();
if (ourSelenium == null) {
session.set(cal = new DefaultSelenium());
}
return ourSelenium;
1 | ThreadLocal.initialValue() |
automatically handles this logic and makes our code a bit neater– especially if we’re calling
1 | get() |
in multiple places.
- In this implementation I also have methods to set the session and end the selenium session.
1 2 3 4 5 6 7 8 9 10 11 12 13 | /** * Set the current selenium session. * @param classInstance */ public static void set(OurDefaultSelenium classInstance) { selenium.set(classInstance); } /** * Method to end the session, should use after the test. */ public static void endSession() { selenium.get().stop(); } |


Leave a Reply