以下代码线程是否安全?
public static Entity getInstance(){
//the constructor below is a default one.
return new Entity();
}
答案 0 :(得分:5)
假设构造函数本身是线程安全的,那很好。
构造函数不是线程安全的,这是非常不寻常的,但可能......即使它调用Entity
的默认自动生成构造函数,基本构造函数也是如此可能不是线程安全的。我不是说这可能,只是可能:)
基本上没有应用于静态方法或实例方法或构造函数的神奇线程安全性。除非同步应用,否则它们可以同时在多个线程上调用。如果他们不提取或更改任何共享数据,它们通常是安全的 - 如果他们 访问共享数据,则需要更加小心。 (如果共享数据是不可变的或只是读取,那通常没问题 - 但是如果其中一个线程会改变它,你需要非常小心。)
只有静态初始化器(静态变量的初始化表达式和static { ... }
直接在类中阻塞)有特殊处理 - VM确保它们只执行一次,阻止其他等待类型的线程待初始化。
答案 1 :(得分:4)
这取决于Entity构造函数的细节。如果Entity构造函数修改了共享数据,则它不是。
答案 2 :(得分:2)
它可能是线程安全的,但有什么意义呢?如果您只是使用工厂方法重定向到默认构造函数,那么为什么不首先使用构造函数?所以问题是:你想要实现什么目标?名称getInstance()
表示单身人士(至少是常见做法),但你显然没有单身人士。如果你想要一个单例,请使用这样的静态内部持有者类:
public class Singleton {
private Singleton() {
}
public static Singleton getInstance() {
return InstanceHolder.INSTANCE;
}
private static final class InstanceHolder {
public static final Singleton INSTANCE = new Singleton();
}
}
但如果你不这样做,为什么还要使用这样的工厂方法,因为你没有通过它添加任何值(方法名称语义,对象池,同步等)
答案 3 :(得分:1)
线程安全是关于访问不同线程之间的共享数据。示例中的代码本身不访问共享数据,但它是否是线程安全的取决于构造函数是否访问可以在不同线程之间共享的数据。
关于并发编程,有很多微妙和难以处理的问题。如果您想了解Java中的线程安全和并发编程,那么我强烈推荐Brian Goetz撰写的这本书Java Concurrency in Practice。
答案 4 :(得分:0)
多个线程可以调用此方法,每个线程都将获得一个“实体”的唯一实例。所以这个方法“本身”是线程安全的。但是如果构造函数或其中一个非线程安全的超级构造函数中存在代码,则无论如何都可能存在安全问题。