gpt4 book ai didi

multithreading - java :singleton, 静态变量和线程安全

转载 作者:行者123 更新时间:2023-12-01 16:19:33 25 4
gpt4 key购买 nike

class MyClass
{
private static MyClass obj;

public static MyClass getInstance()
{
if(obj==null)
{
obj = new MyClass();
}
return obj;
}

在上面的java代码示例中,由于obj是类内部的静态变量,getInstance 仍然是非线程安全的吗?因为静态变量由所有线程共享,所以 2 个并发线程应使用同一个对象。不是吗?

维普尔沙阿

最佳答案

因为静态变量被广泛共享,所以它们是极度非线程安全的。

考虑如果两个线程同时调用您的 getInstance 会发生什么。两个线程都将查看共享静态 obj两个线程都会看到 obj在 if 检查中为 null。然后两个线程都会创建一个新的 obj .

您可能会想:“嘿,它是线程安全的,因为 obj 永远只有一个值,即使它被多次初始化也是如此。”该声明存在几个问题。在我们之前的示例中,getInstance 的调用者都将获得自己的 obj。后退。如果两个调用者都保留对 obj 的引用那么您将使用多个单例实例。

即使我们之前示例中的调用方只是执行了:MyClass.getInstance();并且没有保存对 MyClass.getInstance(); 的引用返回,您仍然可以最终从这些线程上的 getInstance 获取不同的实例。您甚至可以进入 obj 的新实例的情况即使对 getInstance 的调用没有同时发生,也会创建!

我知道自上次分配给 obj 以来,我的最后一个声明似乎违反直觉似乎是 future 调用 MyClass.getInstance() 可以返回的唯一值.但是,您需要记住,JVM 中的每个线程都有自己的主内存本地缓存。如果两个线程调用 getInstance,它们的本地缓存可能有不同的值分配给 obj以后从这些线程调用 getInstance 将返回它们缓存中的内容。

确保 getInstance 线程安全的最简单方法是使该方法同步。这将确保

  1. 两个线程不能同时进入getInstance
  2. 尝试使用 obj 的线程永远不会得到 obj 的过时值从他们的缓存中

不要尝试变得聪明并使用双重检查锁定: http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html

关于multithreading - java :singleton, 静态变量和线程安全,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5339998/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com