ThreadLocal variable如何降低创建昂贵对象的成本?
例如:
private ThreadLocal<String> myThreadLocal = new ThreadLocal<String>();在上面的代码行中,我们创建了一个ThreadLocal对象,它将为thread.But创建一个对象。我不能理解它如何减少创建实例的成本。
发布于 2017-12-15 12:42:57
昂贵通常意味着它将花费一段时间,但也可能意味着它将占用大量其他资源。
就像实例变量是按实例的一样,ThreadLocal变量也是按线程的。对于创建成本高昂的对象,这是一种实现线程安全的方法。
对于ex。通过将其设置为ThreadLocal,您可以将其设置为线程安全。因为该类的开销很大,所以在本地作用域中使用它并不好,因为在每次调用时都需要单独的实例。
通过为每个线程提供自己的副本:
1)通过重用固定数量的实例来减少昂贵对象的实例数量。
2)线程安全是在没有同步或不变性代价的情况下实现的。
发布于 2017-12-15 13:03:54
ThreadLocal variable如何降低创建昂贵对象的成本?
它不会降低创建对象的成本,ThreadLocal的单个实例可以为每个线程单独存储不同的值。
TheadLocal结构允许我们存储只有特定线程才能访问的数据。
假设我们想要一个与特定线程捆绑在一起的Integer值:
ThreadLocal<Integer> threadLocalValue = new ThreadLocal<>();接下来,当我们想从线程中使用这个值时,我们只需要调用get()或set()方法。简单地说,我们可以认为ThreadLocal将数据存储在映射中-以线程为键。
由于这一事实,当我们在threadLocalValue上调用get()方法时,我们将获得请求线程的Integer值:
threadLocalValue.set(1);
Integer result = threadLocalValue.get();发布于 2017-12-15 14:31:35
变量应该总是在尽可能小的作用域中声明,但是ThreadLocal提供了更大的作用域,并且应该只用于跨多个词法作用域需要的变量。根据doc
这些变量与普通的对应变量的不同之处在于,访问一个变量的每个线程(通过其get或set方法)都有其自己的、独立初始化的变量副本。ThreadLocal实例通常是希望将状态与线程(例如,用户ID或事务ID)相关联的类中的私有静态字段。
因此,当你有一个通用的代码,并且你想要在每个线程的基础上保存状态时,就会使用它们。文档中提供了一个示例:
import java.util.concurrent.atomic.AtomicInteger;
public class ThreadId {
// Atomic integer containing the next thread ID to be assigned
private static final AtomicInteger nextId = new AtomicInteger(0);
// Thread local variable containing each thread's ID
private static final ThreadLocal<Integer> threadId =
new ThreadLocal<Integer>() {
@Override protected Integer initialValue() {
return nextId.getAndIncrement();
}
};
// Returns the current thread's unique ID, assigning it if necessary
public static int get() {
return threadId.get();
}
}在上面的示例中,类ThreadId生成唯一的标识符,该标识符是每个线程的本地标识符,在后续调用中不会更改。只要线程是活动的,并且ThreadLocal实例是可访问的,那么每个线程都持有对其线程本地变量副本的隐式引用;在线程离开后,它的所有线程本地实例副本都将受到垃圾回收的影响。
ThreadLocal variable如何降低创建昂贵对象的成本?
在一些基准测试支持这一说法之前,我不确定最新的JVM是否也是如此。
https://stackoverflow.com/questions/47825765
复制相似问题