Inq*_*ive 7 java concurrency multithreading synchronization thread-local
备受好评的书籍JCIP对ThreadLocal的使用说明了这一点:
通过将其线程限制属性视为使用全局变量的许可或作为创建"隐藏"方法参数的方法,很容易滥用ThreadLocal.线程局部变量可能会降低可重用性并在类之间引入隐藏的耦合,因此应谨慎使用.
说Thread-local变量可以减少可重用性并在类之间引入隐藏的耦合是什么意思?
Tud*_*dor 11
它们以与全局变量相同的方式减少可重用性:当方法的计算依赖于方法外部的状态,但不作为参数传递(例如类字段)时,您的方法不太可重用,因为它紧密耦合到它所在的对象/类的状态(或者更糟糕的是,完全在另一个类上).
编辑:好的,这是一个让它更清晰的例子.我ThreadLocal只是为了问题而使用,但它一般适用于全局变量.假设我想在几个线程上并行计算前N个整数的总和.我们知道最好的方法是计算每个线程的本地总和,然后在最后总结它们.出于某种原因,我们决定call每个方法Task将使用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();
}
}
Run Code Online (Sandbox Code Playgroud)
代码正常工作并为我们提供了全局和的预期值,但我们注意到类Task及其call方法现在严格地与Foo类相关联.如果我想Task在另一个项目中重用该类,我还必须移动Foo该类,否则代码将无法编译.
虽然这是一个简单的复杂示例,但您可以看到"隐藏"全局变量的危险.它还会影响可读性,因为阅读代码的其他人也必须搜索该类Foo并查看其定义Foo.localSum.你应该让你的课程尽可能独立.
| 归档时间: |
|
| 查看次数: |
919 次 |
| 最近记录: |