ThreadLocal Live Project Usage

Anmol Sehgal
4 min readNov 24, 2018

--

If you have worked in a multithreaded environment, you must have come across the term “ThreadLocal”. Consider it just as a type of scope in java, just like other famous scopes like public/private/protected etc. with a difference that it limits the scope only within a particular thread, and hence the name Thread Local, local within the thread.
So if say Thread T1 sets some value in the threadLocal, then no other thread other than T1 can access that value, and similarly same the case with other threads.
So where can we need such a clever API?
Well, not until 2 years of working in Java I used it to the full utility, until when I can across a situation which could have proven very complex to attain without ThreadLocal.

Live Project Usage:

So I had written a data layer library to interact with any data layer(be it database/shared prefs/ Rest calls etc) in Android. It will do all the work in some worker thread and will send the result back to the main thread upon completion/error.
To make it real Asynchronous, I had used the executors i.e. more than one operations were performed at the same time, in different threads.
NOTE: Please see the Executors framework if you are interested in it, which uses multiple queues of threads which keeps on listening to new tasks to perform, and so multiple queues perform multiple tasks at the same time. Will write another article on the internal working on executors as well :)

So basically the high level of the code setup looked like this:

And another class which puts the tasks to this executor like:

So with these 2 classes, the API looked neat and clean. To do any operation we just need to extend OperationExecutorAsync Class and override the perform method of it.
The perform method will run inside the runnable(line 11–16 ->runnable), and this runnable is passed to the execute method which in turn runs inside the executor(line 9–16 of the upper class- OperationExecutor.java). After the perform has executed, it sends the result of it to the onExecution() method, which in turn calls the callback methods on the main thread.

For example, we can have the operation as

So it's that easy.
You can have n number of operations, all independent and performing single responsibility, and having the perform() implementation. The flow looks like:

So far the design looks pretty nice, but it has a small problem.
The perform method which runs on the executor(worker thread) returns only the single value. Here it's of type T. But what it something wrong went on in the perform method and we want to show the error to the user?
With the current implementation, we can return null as the response and can check if its null then means its error. But still, we can't know what the error cause was. For that to know the perform method itself should send it. But it cant return 2 values (T response and String error).
Also, we can wrap the 2 values in some wrapper class having 2 attributes,
T response and String error, but then every time the user of this API uses this, he needs to return that wrapper with the success/error saved in it. It looks doable, but it's not a good design.
Why the operation should return the Wrapper? It should return the result it was going to perform, right? and in case of any error, we can call some method like notifyError() or so, inside it.
like

This looks pretty neater.

But now how to do this? We can have notifyError inside the parent class OperationExecutorAsync which can in turn call notifyError method of our singleton class OperationExecutor. Now OperationExecutor can save this error and can send this error in its onExecution() method like:

A new problem with such a design is if multiple threads are running at same time, and they all set this mError field, then it may cause trouble as other threads may also see this error before this error is nullified.

Here the fun begins :)

Maybe we can somehow map each thread to the error, then we know that this error message is only for that thread, and other threads should ignore it. Or what if only that particular thread can see the error value who set it? That would be amazing. And luckily that comes out of the box with the THREADLOCAL API.

Using threadLocal in such a scenario, say T1 sets error value, now other threads will see error value as null only, and only T1 can see the non-null value. This is the power of Thread Local.

i.e. simply by replacing String Error with ThreadLocal<String> mError we have got the solution.

Please drop comments if anything is unclear or does not make any sense to you. Happy to help you if I can :)

--

--

No responses yet