我在理解以下代码时遇到了问题: -
public class SoCalledSigleton{
private final static boolean allDataLoaded = SoCalledSigleton();
private SoCalledSigleton(){
loadDataFromDB();
loadDataFromFile();
loadDataAgainFromDB();
}
}
这段代码线程安全吗?如果不是那么为什么?
答案 0 :(得分:5)
这将在Java中产生错误。
private final static boolean allDataLoaded = SoCalledSigleton();
new
来实例化变量。但如果您的代码是这样的
public class SoCalledSigleton{
private final static SoCalledSigleton allDataLoaded = new SoCalledSigleton();
private SoCalledSigleton(){
loadDataFromDB();
loadDataFromFile();
loadDataAgainFromDB();
}
}
它是线程安全的,因为静态初始化和静态属性是线程安全的。它们只被初始化一次并存在于整个系统的整个生命周期中。
答案 1 :(得分:2)
(我认为allDataLoaded
应该是SoCalledSigleton
而boolean
只是一个错字: - )
如果类没有其他构造函数,或者loadData*
方法没有做有趣的业务(例如发布this
),那么它的初始化是线程安全的,因为最终静态数据成员的初始化由JVM守卫。首次加载类时,类加载器会初始化这些成员。在此期间,类上有一个锁,因此即使多个线程尝试并行访问该类,初始化过程也是线程安全的。因此,保证类的构造函数只被调用一次(每个类加载器 - 感谢Visage澄清: - )。
请注意,既然你没有向我们展示课程的其余部分(我认为它至少应该有一个static getInstance
方法,可能还有其他非静态成员),我们不能说出是否整个类的实现是否是线程安全的。
答案 2 :(得分:2)
代码在当前形式下无法使用,因此线程安全的任何概念都是无关紧要的。
用户使用什么公共接口来获取单例的实例?
答案 3 :(得分:0)
是的,这是线程安全的。 “方法”是构造函数,它将在加载类时调用,即恰好一次。
但是看看正在完成的工作,我认为从类加载器调用它可能是一个糟糕的想法。从本质上讲,当代码中的某些内容触及SoCalledSingleton
时,您最终会完成数据库连接和事务。有可能,这不会出现在一些明确定义的事件序列中,如果出现错误,您可以使用catch
块来进行一些有用的GUI消息处理或其他任何事情。
“更干净”的方法是使用synchronized
static getInstance()
方法,该方法将构建您的类并在第一次调用getInstance()
时准确调用其代码。
编辑:正如精英绅士所指出的,那里存在语法错误。你需要说
private final static SoCalledSingleton allDataLoaded = new SoCalledSigleton();
答案 4 :(得分:0)
从我们看到的内容,没有具体的问题 - 保证构造函数只会被调用一次(因此根据定义不能运行多线程),我认为是什么你担心的。
但是,仍有可能存在问题。首先,如果loadData...
方法是公共的,那么任何人都可以随时调用它们,很可能会导致并发错误。
此外,这些方法可能会在某处修改某种类型的集合。如果在构造函数返回之前公开访问这些集合,那么您可以很容易地再次遇到并发问题。这可能是更新特定于实例的字段的任何异常的问题(静态字段可能会也可能不会出现此问题,具体取决于文件中定义的位置)。
根据类的使用方式,只需编写所有单线程数据可能都不够好。即使只读,集合类对于多线程访问也不一定安全,因此如果多个线程可能访问您的单例,则需要确保使用线程安全的数据结构。
也可能存在其他问题。线程安全不是一个简单的检查列表;您需要考虑可以同时访问哪些代码/数据,并确保采取适当的操作(声明方法synchronized
,使用并发集合等)。线程安全也不是二元的东西(即本身没有“线程安全”的东西);它取决于一次访问类的线程数量,方法的哪些组合是线程安全的,操作序列是否会继续按预期运行(你可以使一个类“线程安全”,因为它不是崩溃,但某些返回值如果被抢占则是未定义的),监视线程需要保持什么以保证某些不变量等。
我想我想说的是你需要思考并理解如何使用这个类。向人们显示半个文件的快照(甚至不编译),并要求他们给出是/否答案,这不会有益。如果有的话,他们最好会为你指出一些的问题;在最坏的情况下,你会有一种虚假的自信心。