在Java中实现单例设计模式的有效方法是什么?
当前回答
Java 5+中的线程安全:
class Foo {
private static volatile Bar bar = null;
public static Bar getBar() {
if (bar == null) {
synchronized(Foo.class) {
if (bar == null)
bar = new Bar();
}
}
return bar;
}
}
注意此处的挥发性修饰语。:)这很重要,因为如果没有它,JMM(Java内存模型)就不能保证其他线程看到其值的更改。同步不会处理这一点——它只序列化对该代码块的访问。
@Bno的回答详细介绍了Bill Pugh(FindBugs)推荐的方法,并且可以更好地进行论证。去阅读并投票支持他的答案。
其他回答
有四种方法可以在Java中创建单例。
Eager初始化单例公共类测试{私有静态最终测试=新测试();专用测试(){}公共静态测试getTest(){回归试验;}}惰性初始化单例(线程安全)公共类测试{私人静态挥发性测试;专用测试(){}公共静态测试getTest(){if(测试==空){同步(Test.class){if(测试==空){test=新测试();}}}回归试验;}}Bill Pugh单例与持有者模式(最好是最好的一个)公共类测试{专用测试(){}私有静态类TestHolder{私有静态最终测试=新测试();}公共静态测试getInstance(){return TestHolder.test;}}枚举单例公共枚举MySingleton{实例;私有MySingleton(){System.out.println(“此处”);}}
忘记延迟初始化;这太有问题了。这是最简单的解决方案:
public class A {
private static final A INSTANCE = new A();
private A() {}
public static A getInstance() {
return INSTANCE;
}
}
我使用Spring框架来管理我的单件。
它并没有强制实现类的“单例性”(如果涉及多个类加载器,则无论如何都无法做到这一点),但它提供了一种非常简单的方法来构建和配置不同的工厂以创建不同类型的对象。
以下是三种不同的方法
枚举/***使用Java Enum的Singleton模式示例*/公共枚举EasySingleton{实例;}双重检查锁定/延迟加载/***带有双重检查锁定的单线模式示例*/公共类DoubleCheckedLockingSingleton{私有静态易失性DoubleCheckedLockingSingleton INSTANCE;private DoubleCheckedLockingSingleton(){}公共静态DoubleCheckedLockingSingleton getInstance(){如果(INSTANCE==null){synchronized(DoubleCheckedLockingSingleton.class){//双重检查Singleton实例如果(INSTANCE==null){INSTANCE=新的DoubleCheckedLockingSingleton();}}}返回INSTANCE;}}静态工厂方法/***带有静态工厂方法的Singleton模式示例*/公开课Singleton{//在类加载期间初始化private static final Singleton INSTANCE=new Singleton();//防止创建另一个“Singleton”实例私有Singleton(){}公共静态Singleton getSingleton(){返回INSTANCE;}}
版本1:
public class MySingleton {
private static MySingleton instance = null;
private MySingleton() {}
public static synchronized MySingleton getInstance() {
if(instance == null) {
instance = new MySingleton();
}
return instance;
}
}
延迟加载,线程安全,阻塞,由于同步,性能低下。
版本2:
public class MySingleton {
private MySingleton() {}
private static class MySingletonHolder {
public final static MySingleton instance = new MySingleton();
}
public static MySingleton getInstance() {
return MySingletonHolder.instance;
}
}
延迟加载,线程安全,无阻塞,高性能。
推荐文章
- 创建正则表达式匹配数组
- 我如何在Java中初始化一个全零的数组列表?
- 主体、使用者和主体之间的意义和区别是什么?
- 将字节转换为十六进制
- HashSet和HashMap的区别?
- 我如何有效地解析HTML与Java?
- Java构造函数继承
- 如何在Java中将int[]转换为Integer[] ?
- 你能解释一下流的概念吗?
- 导致java.lang.VerifyError错误的原因
- 如何在Java中监控计算机的CPU、内存和磁盘使用情况?
- 如何设置超时在改造库?
- java lambda可以有一个以上的参数吗?
- HashMap -获取第一个键值
- 使用Jackson将JSON字符串转换为漂亮的打印JSON输出