如何ThreadLocal的使用减少的可重用性(How does ThreadLocal usage

2019-09-18 21:28发布

该井广受好评的书JCIP说,这大约ThreadLocal的用法:

这是很容易处理的线程限制特性为许可使用全局变量或为创建“隐藏”方法参数的手段滥用的ThreadLocal。 线程局部变量可以重用减损和类之间引入潜在联轴器,因此应小心使用。

这是什么说的是线程局部变量可以减少可重用性和类之间引入潜在联轴器是什么意思?

Answer 1:

它们减少了可重用性在大致相同的方式,全局变量做:当你方法的计算结果取决于状态,这是外部的方法,而不是作为参数传递(即,例如类字段),你的方法不太可重复使用的,因为它是紧耦合到对象/类它在其中驻留(或更糟的是,在不同的类完全地)的状态。

编辑 :好吧,这里以使其更清晰的例子。 我使用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();
    }
}

该代码工作正常,并为我们提供了全球总和的预期值,但我们注意到,类Task和它的call方法现在严格耦合到Foo阶级。 如果我想重用Task在另一个项目类,我还必须移动Foo阶级否则代码将无法编译。

虽然这是一个简单的例子复杂的目的,你可以看到“隐藏”的全局变量的危险。 这也影响可读性,因为别人读的代码都还搜索类Foo ,看看是什么的定义Foo.localSum是。 您应该保留类作为自成体系越好。



Answer 2:

一个ThreadLocal是每个线程声明-以此为出发点- -通常是场每该类的对象声明可以有一大堆的事情,如果可能出错ThreadLocal被滥用。

如果一个线程穿过多个对象,(无论是单个类或多个类的),则ThreadLocal由该线程使用在所有这些实例相同的实例。 这是BG正在谈论的耦合。 当下有一个耦合 - 可重用性变得困难,而且容易出错。



文章来源: How does ThreadLocal usage reduce reusability