1.饿汉式:急切
public class Singleton{
private static Singleton singleton = new Singleton();//private保证不能被外部修改 static保证实例只有一个
private Singleton(){};//保证不能被外部类实例化
public Singleton getInstance(){
return singleton;
}
}
2.懒汉式:
public class Singleton{
private static Singleton singleton = null;//private保证不能被外部修改 static保证实例只有一个
private Singleton(){};//保证不能被外部类实例化
public Singleton getInstance(){
if(null==singleton){
Thread.sleep(20);
singleton=new Singleton(); //如果不判断直接new就是新对象。 多线程情况下有线程安全问题
}
return singleton;
}
}
懒汉式线程安全问题解决方法:
1.直接在get方法上加synchronized关键字,缺点是改成串行化同步慢
2.改成饿汉式。 类变量每次调用static方法时初始化
3.双重检查
public class Singleton{
private static volatile Singleton singleton = null;//private保证不能被外部修改 static保证实例只有一个
private Singleton(){};//保证不能被外部类实例化
public Singleton getInstance(){
if(null==singleton){ //如果不判断都竞争锁资源
synchoronized(Singleton.class){
if(null == singleton){ 如果不判断直接new就是新对象。多线程情况下有线程安全问题
singleton=new Singleton(); }
}
}
return singleton;
}
}
4.静态内部类
public class Singleton{
private static Singleton singleton = null;//private保证不能被外部修改 static保证实例只有一个
private Singleton(){};//保证不能被外部类实例化
private static class SingleHolder{
static Singleton singleton=new Singleton(); //利用静态内部类只实例化一次
}
public static Singleton getInstance(){
return SingleHolder.singleton;
}
}
5.枚举
public class Singleton{
private static Singleton singleton = null;//private保证不能被外部修改 static保证实例只有一个
private Singleton(){};//保证不能被外部类实例化
private enum SingleEnum{
Instance;
private Singleton singleton;
SingleEnum(){
singleton=new Singleton(); //利用枚举类只实例化一次
}
}
public static Singleton getInstance(){
return SingleEnum.Instance.singleton;
}
}