ThreadLocal的用法如何降低可重用性 [英] How does ThreadLocal usage reduce reusability

查看:292
本文介绍了ThreadLocal的用法如何降低可重用性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

The well acclaimed book JCIP says this about ThreadLocal usage :

这是很容易被滥用的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.

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

What does it mean by saying that Thread-local variables can reduce reusability and introduce hidden couplings among classes?

推荐答案

它们减少了可重用性与全局变量的方式大致相同:当方法的计算依赖于方法外部的状态,而不是作为参数传递(例如,类字段)时,您的方法不太可重用,因为它与状态紧密耦合

They reduce reusability in much the same way that global variables do: when you method's computations depend on state which is external to the method, but not passed as parameters (i.e. class fields for example), your method is less reusable, because it's tightly coupled to the state of the object/class in which it resides (or worse, on a different class entirely).

编辑:好的,这里有一个例子它更清楚。我使用 ThreadLocal 只是为了这个问题,但它一般适用于全局变量。假设我想在几个线程上并行计算前N个整数的和。我们知道,最好的方法是计算每个线程的本地和,并在最后对它们求和。由于某种原因,我们决定每个任务调用方法将使用 ThreadLocal sum 变量在不同类中定义为全局(静态)变量:

Edit: Ok, here's an example to make it more clear. I've used ThreadLocal just for the sake of the question, but it applies to global variables in general. Assume I want to calculate the sum of the first N integers in parallel on several threads. We know that the best way to do it is to calculate local sums for each thread and them sum them up at the end. For some reason we decide that the call method of each Task will use a ThreadLocal sum variable which is defined in a different 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();
    }
}

代码可以正常工作,全局总和,但我们注意到 Task 及其方法现在严格耦合到 Foo 类。如果我想在另一个项目中重用 Task 类,我还必须移动 Foo 类,否则代码不会编译。

The code works correctly and gives us the expected value of the global sum, but we notice that the class Task and its call method are now strictly coupled 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.

虽然这是一个简单的例子复杂的目的,你可以看到隐藏的全局变量的危险。它也会影响可读性,因为有人读代码还必须搜索类 Foo ,看看 Foo.localSum is。你应该尽可能保持自己的课程。

Although this is a simple example complicated on purpose, you can see the perils of "hidden" global variables. It also affects readability, since someone else reading the code will have to also search for the class Foo and see what the definition of Foo.localSum is. You should keep your classes as self-contained as possible.

这篇关于ThreadLocal的用法如何降低可重用性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆