广受好评的书JCIP这是关于 ThreadLocal 用法的:
It is easy to abuse ThreadLocal by treating its thread confinement property as a license to use global variables or as a means of creating "hidden" method arguments. Thread-local variables can detract from reusability and introduce hidden couplings among classes, and should therefore be used with care.
线程局部变量会降低可重用性并在类之间引入隐藏耦合是什么意思?
最佳答案
它们降低可重用性的方式与全局变量非常相似:当你的方法的计算依赖于方法外部的状态,但不作为参数传递(例如类字段)时,你的方法的可重用性较低,因为它与它所在的对象/类的状态紧密耦合(或者更糟,完全不同的类)。
编辑:好的,这里有一个例子可以让它更清楚。我使用 ThreadLocal
只是为了这个问题,但它通常适用于全局变量。假设我想在多个线程上并行计算前 N 个整数的总和。我们知道最好的方法是计算每个线程的局部总和,最后将它们相加。出于某种原因,我们决定每个 Task
的 call
方法将使用一个 ThreadLocal sum
变量,该变量在不同的类中定义为全局变量(静态)变量:
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();
}
}
代码工作正常并为我们提供了全局总和的预期值,但我们注意到类 Task
及其 call
方法现在严格耦合到 Foo
类。如果我想在另一个项目中重用 Task
类,我还必须移动 Foo
类,否则代码将无法编译。
虽然这是一个故意复杂化的简单示例,但您可以看到“隐藏”全局变量的危险。它还会影响可读性,因为阅读代码的其他人也必须搜索类 Foo
并查看 Foo.localSum
的定义是什么。您应该让您的类(class)尽可能独立。
关于java - ThreadLocal 的使用如何降低可重用性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11283369/