kil*_*joy 7 java multithreading
ThreadLocal确保字段是全局的并且是线程的本地字段.(全局因为它可用于线程和本地中的所有方法,因为它仅限于该线程的堆栈.)
这对我来说没什么意义,因为每个线程的堆栈仅限于该线程.所以它已经是'threadlocal',对吧?
为什么我们需要ThreadLocal?- 在进一步阅读时,我确认了我从各个站点(其中大多数未能提供这些事实或相互矛盾)的假设,这确实适用于静态字段.哪个有意义.
所以我的问题是,是否有一个多线程场景,ThreadLocal可以/需要应用于非静态字段?(我发现有些网站说'ThreadLocal' 主要用于静态字段;甚至https://docs.oracle.com/javase/7/docs/api/java/lang/ThreadLocal.html使用" 通常 ")
我认为这个问题是基于一个错误的前提.
ThreadLocal确保字段是全局的并且是线程的本地字段.(全局因为它可用于线程和本地中的所有方法,因为它仅限于该线程的堆栈.)
这不是"全球"的真正含义.全球真的意味着整个计划无法获得任何资格.实际上,Java没有真正的全局变量.它最接近的是"公共静态"字段......可以通过限定访问.
但回到问题......
如果满足两个条件,则threadlocal 变量可用于方法:
方法调用必须在正确的线程上.(如果它位于不同的线程上,则会看到另一个变量.)
该方法必须能够获得ThreadLocal有效"声明"线程局部变量的对象(在任何线程中).
第二个条件是否暗示"声明"是全球性的?
国际海事组织,没有.有两个原因.
传统意义上的全局变量只有一个实例.本地线程为每个线程都有一个不同的实例.
ThreadLocal特定方法可访问的事实不会使任何方法都可以访问它.a的正常(和良好实践)使用模式ThreadLocal是将对象引用保存在private static变量中.这意味着同一个类中的方法可以使用相应的线程局部变量实例...但其他类中的方法不能.
现在可以将引用ThreadLocal放在public static变量中,但为什么要这样做呢?您明确地创建了漏洞抽象 ......这可能会导致问题.
当然,你可以做@ Radiodef的回答所显示的内容; 即创建一个本地线程,其实例只能从特定类的特定实例上的方法访问.但很难理解为什么你想要/需要达到那种限制水平.(并且它可能导致存储泄漏......)
简短回答:如果您不希望可以访问线程局部变量,请限制对该ThreadLocal对象的访问.
只有局部变量位于线程的堆栈上。* 静态变量和实例变量都位于堆上。如果我们愿意,我们也可以只传递一个ThreadLocal本身,而不需要它存在于对象或类中。
我们可以将其视为ThreadLocal可以在任何时间点访问的局部变量。
普通局部变量在其声明的作用域返回时会被销毁,但 aThreadLocal可以存在于任何地方。
所以我的问题是,是否存在 ThreadLocal 可以/需要应用于非静态字段的多线程场景?
我们可以补一个...
interface Dial {}
class Gadget {
ThreadLocal<Dial> d = new ThreadLocal<>();
}
class Gizmo implements Runnable {
Gadget g;
Gizmo(Gadget g) {
this.g = g;
}
public void run() {}
}
{
Gadget g = new Gadget();
new Thread(new Gizmo(g)).start();
new Thread(new Gizmo(g)).start();
}
Run Code Online (Sandbox Code Playgroud)
两个线程共享相同的实例,Gadget但有自己的本地Dial.
那么为什么我们需要ThreadLocal呢?
事实上,我们并不ThreadLocal经常需要,甚至根本不需要。
* 只有局部变量位于线程的堆栈上,除非在理论优化的情况下,允许 JVM 执行可以在堆栈上分配对象的操作。如果发生这种情况,我们永远不会发现,因为不允许改变程序的行为。如果一个对象在线程之间共享,则它位于堆上。