一,饱汉
public class SingleTon {
private SingleTon(){
}
private final static SingleTon instance = new SingleTon();
public static SingleTon getInstance(){
return instance;
}
public static void main(String[] args) {
System.out.println("Main方法");
}
}
或
public class SingleTon {
private SingleTon(){
}
public final static SingleTon instance = new SingleTon();
}
二,饿汉,延迟初始化
public class SingleTon2 {
private SingleTon2() {
System.out.println("构造方法");
}
private static SingleTon2 instance = null;
public static synchronized SingleTon2 getInstance() {
if (instance == null) {
instance = new SingleTon2();
}
return instance;
}
}
二.二 也算是饿汉,但是减少synchronized性能开销的同时,避免double-checked locking
public class SingleTon4 {
private static volatile SingleTon4 instance = null;
private SingleTon4(){}
public static SingleTon4 getInstance(){
if(instance == null){
synchronized (SingleTon4.class) {
if(instance == null){
instance = new SingleTon4();
}
}
}
return instance;
}
}
三,基于类初始化的解决方案。线程安全的延迟初始化方案
JVM在类的初始化阶段(即在Class被加载后,且被线程使用之前),会执行类的初始化。
在执行类的初始化期间,JVM会去获取一个锁。这个锁可以同步多个线程对同一个类的初始化。
基于这个特性,可以实现另一种线程安全的延迟初始化方案(这个方案被称之为Initialization On Demand Holder idiom)
public class SingleTon5 {
private SingleTon5(){
System.out.println("heihi");
}
private static class InstanceHolder {
public static SingleTon5 instance = new SingleTon5();
}
public static SingleTon5 getInstance() {
return InstanceHolder.instance ; //这里将导致InstanceHolder类被初始化
}
}
四,枚举类实现
/**
* 单元素的枚举类型是实现单例的最佳方法
*/
public enum SingleEnum {
INSTANCE;
public void sayHello(){
System.err.println("Hello me");
}
}
五,记录式单例
jkd8
public class SingleTon3_3 {
private static Map<String, SingleTon3_3> map = new HashMap<String, SingleTon3_3>();
private SingleTon3_3(String name) {}
public static SingleTon3_3 getInstance(String name) {
name = Objects.toString(name, SingleTon3_3.class.getName());
return map.computeIfAbsent(name, SingleTon3_3::new);
}
}
jdk7
/**
* 记录式单例
*/
public class SingleTon3 {
private static Map<String, SingleTon3> map = new HashMap<String, SingleTon3>();
static {
SingleTon3 single = new SingleTon3();
map.put(single.getClass().getName(), single);
}
private SingleTon3() {
System.out.println("构造method");
}
public static SingleTon3 getInstance(String name) {
if (name == null) {
name = SingleTon3.class.getName();
}
if (map.get(name) == null) {
System.out.println("得到" + name);
try {
map.put(name, (SingleTon3) Class.forName("single_ton.SingleTon3").newInstance());
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
return map.get(name);
}
}