Java vs .NET: Which Is Better For Your Business? | PixelCrayons
ThreadLocal
It is one of the interesting areas in Threading field.
You can get a lot of material over this topic on internet, so I will not go though that part here.
Even name suggests that it is going to be local to thread, but you can't take it for granted.
Before going for ThreadLocal use in your code, think & analyze the requirements properly to confirm its use.
Below I have tried to put one limitation & you have to think about this before going for ThreadLocal in your code-
public class ThreadLocals {
public static void main(String[] args) {
SomeThread st1 = new SomeThread();
Thread t1 = new Thread(st1);
t1.setName("t1");
Thread t2 = new Thread(st1);
t2.setName("t2");
t1.start();
t2.start();
}
}
class SomeThread implements Runnable {
private String common = "Nitin";
private ThreadLocal<HashMap<String, String>> tl = new ThreadLocal<>();
@Override
public void run() {
HashMap<String, String> map = new HashMap<>(); //This line needs to be noted
map.put("name", common);
tl.set(map);
if(common.equals("Nitin") && Thread.currentThread().getName().equals("t1")){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
print();
common = "Nit";
map.put("name", common);
tl.set(map);
}
public void print() {
System.out.println(common);
System.out.println(tl.get().get("name"));
}
}
Output : Common: Nitin
ThreadLocal: Nitin
Common: Nit
ThreadLocal: Nitin
Explanation : Here String variable 'common' is like normal declaration, so any change into its value by one thread is visible in other thread also. As shown in above output. But any change in above threadlocal variable, is not visible in other thread.
As you can see both threads gave same value.
So it looks, ThreadLocal will resolve our every problem where we need to safeguard the variables in multithreaded environments.
But lets see below code first -
public class ThreadLocals {
public static void main(String[] args) {
SomeThread st1 = new SomeThread();
Thread t1 = new Thread(st1);
t1.setName("t1");
Thread t2 = new Thread(st1);
t2.setName("t2");
t1.start();
t2.start();
}
}
class SomeThread implements Runnable {
private String common = "Nitin";
private HashMap<String, String> map = new HashMap<>();
private ThreadLocal<HashMap<String, String>> tl = new ThreadLocal<>();
@Override
public void run() {
map.put("name", common);
tl.set(map);
if(common.equals("Nitin") && Thread.currentThread().getName().equals("t1")){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
print();
common = "Nit";
map.put("name", common);
}
public void print() {
System.out.println("Common: " + common);
System.out.println("ThreadLocal: " + tl.get().get("name"));
}
}
Output: Common: Nitin
ThreadLocal: Nitin
Common: Nit
ThreadLocal: Nit
Oops, I didn't even make any change in threadlocal variable but still it is showing different value in other thread.
Why? Because ThreadLocal is making that variable as local but if it is holding some object then it is not making that object
local to thread. So is the case here too. Till hashmap was in run(), it was, by default, local to thread. So ThreadLocal
variable was able to behave as expected, but sooner we moved hashmap variable outside run(), things went out-of-control for ThreadLocal too.
So check for these points also before you start relying on ThreadLocal for every problem. Some cases you will find, where you don't need ThreadLocal.
You can get a lot of material over this topic on internet, so I will not go though that part here.
Even name suggests that it is going to be local to thread, but you can't take it for granted.
Before going for ThreadLocal use in your code, think & analyze the requirements properly to confirm its use.
Below I have tried to put one limitation & you have to think about this before going for ThreadLocal in your code-
public class ThreadLocals {
public static void main(String[] args) {
SomeThread st1 = new SomeThread();
Thread t1 = new Thread(st1);
t1.setName("t1");
Thread t2 = new Thread(st1);
t2.setName("t2");
t1.start();
t2.start();
}
}
class SomeThread implements Runnable {
private String common = "Nitin";
private ThreadLocal<HashMap<String, String>> tl = new ThreadLocal<>();
@Override
public void run() {
HashMap<String, String> map = new HashMap<>(); //This line needs to be noted
map.put("name", common);
tl.set(map);
if(common.equals("Nitin") && Thread.currentThread().getName().equals("t1")){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
print();
common = "Nit";
map.put("name", common);
tl.set(map);
}
public void print() {
System.out.println(common);
System.out.println(tl.get().get("name"));
}
}
Output : Common: Nitin
ThreadLocal: Nitin
Common: Nit
ThreadLocal: Nitin
Explanation : Here String variable 'common' is like normal declaration, so any change into its value by one thread is visible in other thread also. As shown in above output. But any change in above threadlocal variable, is not visible in other thread.
As you can see both threads gave same value.
So it looks, ThreadLocal will resolve our every problem where we need to safeguard the variables in multithreaded environments.
But lets see below code first -
public class ThreadLocals {
public static void main(String[] args) {
SomeThread st1 = new SomeThread();
Thread t1 = new Thread(st1);
t1.setName("t1");
Thread t2 = new Thread(st1);
t2.setName("t2");
t1.start();
t2.start();
}
}
class SomeThread implements Runnable {
private String common = "Nitin";
private HashMap<String, String> map = new HashMap<>();
private ThreadLocal<HashMap<String, String>> tl = new ThreadLocal<>();
@Override
public void run() {
map.put("name", common);
tl.set(map);
if(common.equals("Nitin") && Thread.currentThread().getName().equals("t1")){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
print();
common = "Nit";
map.put("name", common);
}
public void print() {
System.out.println("Common: " + common);
System.out.println("ThreadLocal: " + tl.get().get("name"));
}
}
Output: Common: Nitin
ThreadLocal: Nitin
Common: Nit
ThreadLocal: Nit
Oops, I didn't even make any change in threadlocal variable but still it is showing different value in other thread.
Why? Because ThreadLocal is making that variable as local but if it is holding some object then it is not making that object
local to thread. So is the case here too. Till hashmap was in run(), it was, by default, local to thread. So ThreadLocal
variable was able to behave as expected, but sooner we moved hashmap variable outside run(), things went out-of-control for ThreadLocal too.
So check for these points also before you start relying on ThreadLocal for every problem. Some cases you will find, where you don't need ThreadLocal.