定义
保证只能获取到一个对象实例,如某辆列车的余票数量.
示例
1.1 饿汉模式
public class SingletonDemo1 {
//构造函数私有,保证不能外部new创建
private SingletonDemo1(){
}
//静态变量singleton在类加载时被初始化,final保证不可以被重定向为null.
private static final SingletonDemo1 singleton = new SingletonDemo1();
//获取实例
public static SingletonDemo1 getInstance(){
return singleton;
}
}
注:多数时候是否懒加载对性能影响不大,可以使用.
1.2 饿汉模式变种
public class SingletonDemo2 {
//私有构造函数
private SingletonDemo2(){
}
private static final SingletonDemo2 singleton;
//静态代码块中初始化,和demo1无区别
static{
singleton = new SingletonDemo2();
}
public static SingletonDemo2 getInstance(){
return singleton;
}
}
和1中并无区别.
1.3 懒汉模式
public class SingletonDemo3 {
private SingletonDemo3(){
}
private static SingletonDemo3 singleton;
//同步保证了线程安全,不会出现创建多个对象,但效率较低.
public static synchronized SingletonDemo3 getInstance(){
if(singleton == null){
singleton = new SingletonDemo3();
}
return singleton;
}
}
注:实现了懒加载,但每次校验是否为空都要进入同步,效率低下.
1.4 懒汉模式变种:双重校验锁
public class SingletonDemo4 {
private SingletonDemo4(){
}
//volatile关键字保证了变量在多个线程中修改的可见性
private static volatile SingletonDemo4 singleton;
public static SingletonDemo4 getInstance(){
//双重校验锁,在对象已经被初始化后,无需进入同步方法.效率较demo3高.
if(singleton == null){
synchronized (SingletonDemo4.class) {
if(singleton == null){
singleton = new SingletonDemo4();
}
}
}
return singleton;
}
}
注:只在第一次判断实例为空时,才进入第二次同步判断,效率较3中高.
注:volatile修饰变量时,保证了变量在一个线程中被修改后,在其他线程中的可见性,但不能保证变量操作的原子性.
1.5 匿名内部类
public class SingletonDemo5 {
private SingletonDemo5(){
}
//在SingletonDemo5被加载时,SingletonInstance并未被加载
private static class SingletonInstance{
private static final SingletonDemo5 singleton = new SingletonDemo5();
}
public static SingletonDemo5 getInstance(){
return SingletonInstance.singleton;
}
}
注:另一种懒汉模式的实现.
1.6 枚举
public enum SingletonDemo6 {
INSTANCE;
public void doSomething(){
}
}
线程安全,清晰简洁,推荐使用.