我看到以下可变类的结构:
public class Doubtful
{
public static Doubtful getInstance()
{
DoubtfulContext doubtfulcontext;//LOCAL HEAP VARIABLE
//...
doubtfulcontext = new DoubtfulContext(s1, new PrincipalName(s),
DefaultConfig.getInstance());
//...
doubtfulcontext.setDoubtfulStore(new DoubtfulStore(new File(s2)));
doubtfulcontext.setKeyTab(...);
doubtfulcontext.setSupportedEncryptionTypes(ai);
//...
return new Doubtful(doubtfulcontext);
}
// ...
}
虽然 Doubtful 可能是不可变的,但 DoubtContext 绝对是可变的。
这是线程安全的吗?
本地堆变量在这里有何相关性?
最佳答案
局部变量仅限于执行线程。它们存在于执行线程的堆栈中,其他线程无法访问。这使得 getInstance
方法的执行线程安全。
正如您所说,Doubtful
是不可变的,这使得它是线程安全的:多个线程可以使用同一个 Doubtful
实例,而不会影响其他使用相同的线程>可疑
实例。因为线程无法更改实例变量(Doubtful
是不可变的),并且方法局部变量仅限于执行线程。
现在 DoubtfulContext
是可变的,并且您正在发布对 DoubtfulContext
实例的引用,该实例是在方法 getInstance
中本地创建的:
doubtfulcontext = new DoubtfulContext(s1, new PrincipalName(s),
DefaultConfig.getInstance());
...
return new Doubtful(doubtfulcontext);//Publishes the reference to DoubtfulContext
这会违反堆栈限制。并且多个线程有可能访问同一 DoubtfulContext
实例的共享、可变数据。如果 DoubtfulContext 是非线程安全对象,那么这会破坏您的程序。
考虑一个线程 T1
,它调用 getInstance
来获取 Doubtful
的实例,之后它可能会共享 DoubtfulContext
code> 引用(与 Doubtful
一起出现)与其他线程:
1. Doubtful doubtful = Doubtful.getInstance();
2. DoubtfulContext doubtfulContext = doubtful.getDoubtfulContext();
3. new Thread(new SomeRunnable(doubtfulContext)).start();
4. doubtfulContext.chnageSomeState();
在第 3 行,它使用 DoubtfulContext
创建一个新的执行线程。现在两个线程具有相同的 DoubtfulContext
。如果 DoubtfulContext 是非线程安全的(对实例变量具有非同步访问),那么这将破坏程序的线程安全性。
关于java - 方法的线程安全,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19534694/