How Using ThreadLocal Reduces Reuse

The well-known JCIP book talks about using ThreadLocal:

It is easy to abuse ThreadLocal by treating its thread restriction property as a license to use global variables or as a means of creating “hidden” method arguments. Stream local variables can distract from reuse and introduce hidden relationships between classes, so they should be used with caution.

What does this mean by saying that streaming local variables can reduce reuse and introduce hidden relationships between classes?

+6
source share
2 answers

They reduce reuse in much the same way as global variables: when a method’s calculations depend on a state that is external to the method but not passed as parameters (for example, class fields), your method is less commonly used because it is closely related to the state of the object / class in which it is located (or, even worse, in another class).

Edit : Ok, here is an example to make it more understandable. I used ThreadLocal just for the sake of the question, but it applies to global variables in general. Suppose I want to calculate the sum of the first N integers in parallel across multiple threads. We know that the best way to do this is to calculate local amounts for each thread, and they sum them up at the end. For some reason, we decided that the call method for each Task would use the ThreadLocal sum variable, which is defined in another class as a global (static) variable:

 class Foo { public static ThreadLocal<Long> localSum = new ThreadLocal<Long>() { public Long initialValue() { return new Long(0); } }; } class Task implements Callable<Long> { private int start = 0; private int end = 0; public Task(int start, int end) { this.start = start; this.end = end; } public Long call() { for(int i = start; i < end; i++) { Foo.localSum.set(Foo.localSum.get() + i); } return Foo.localSum.get(); } } 

The code works correctly and gives us the expected value of the global sum, but we notice that the Task class and its call method are now strictly related to the Foo class. If I want to reuse the Task class in another project, I must also move the Foo class, otherwise the code will not compile.

Although this simple example is complex, you can see the dangers of “hidden” global variables. It also affects readability, as someone else reading the code will also have to look for the Foo class and see what the definition of Foo.localSum . You should keep your classes as autonomous as possible.

+10
source

A ThreadLocal declared for each thread - usually a field is declared on an object of this class - starting from this - there can be a lot of things that can go wrong if you use ThreadLocal .

If a thread passes through several objects (one of the same class or several classes), the ThreadLocal used by this thread is the same instance in all of these instances. This is evidenced by the connection of BG. The moment there is a connection, reuse becomes difficult and error prone.

+3
source

Source: https://habr.com/ru/post/919432/


All Articles