1:饿汉式(类加载的时候即创建实例)
2:懒汉式(在需要的时候才创建实例)
3:静态内部类单例 (推荐)
4:双重锁单例
5:枚举单例
//饿汉式
public class SingleTon{
//第二部设置一个内置的对象
private static SingleTon singleTon11=new SingleTon();
//饿汉,线程安全,因为你还没有调用getInstance,就已经创建
//了对象,在加载到内存时就已经创建好了。但是唯一缺点就是,如果实例创建依赖
//其他参数或配置的话,还是需要动态创建,这种加载创建就不能满足了。
//第一步私有化构造器
private SingleTon() {
// TODO Auto-generated constructor stub
}
//提供一个全局访问点
public static SingleTon getinSingleTon() {
return singleTon11;
}
}
//第二种单例模式
//懒汉式
class SingleTon1{
//第二部设置一个内置的对象
private static SingleTon1 singleTon11;
//第一步私有化构造器
private SingleTon1() {
// TODO Auto-generated constructor stub
}
//提供一个全局访问点
public static SingleTon1 getinSingleTon() {
if (singleTon11==null) {
singleTon11=new SingleTon1();
//这样写线程安全,就是效率不高,因为同时只能有一个线程调用getInstance()方法
// 但实际上,我们认为只有在程序中第一次调用才需要保证同时只能有一个线程调用
}
return singleTon11;
}
}
//第三种单例模式
//静态内部类
public class SingleTon {
// 推荐单例模式。懒汉/线程安全/性能保障
//另外还有通过枚举实现单例也是推荐
private static class EffectiveHolder{
//内部写一个静态类,来静态内部实现
private static final SingleTon INSTANCE=new SingleTon();
}
public static SingleTon getInstance(){
return EffectiveHolder.INSTANCE;
}
private SingleTon() {
// TODO Auto-generated constructor stub
}
}
//第四种单例模式
//双重锁(不推荐)
public class SingleTon {
//双重锁+禁止指令重排序
//volatile 禁止指令重排序,因为在jvm中创建一个对象,大致会有三个步骤
//1:给instance分配内存
//2:调用构造函数初始化成员变量
//3:将对象指向分配的空间
//由于jvm在创建对象的时候会进行指令优化,因此步骤可以是1-2-3,也可以是
//1-3-2。我们知道执行第三句指向分配的空间之后,instance就不是null了
//那么如果是第二种情况1-3-2,执行3之后,就被另一个线程抢占了,那么2还没有
//执行,也就是还没有初始化成员变量,因此当使用instance调用成员变量就会有问题
//jdk5之后volatile才有用。
private volatile static SingleTon instance;
public static SingleTon getInstance(){
if(instance==null){
synchronized(SingleTon.class){
if(instance==null){
instance=new SingleTon();
}
}
}
return instance;
}
}
//第五种单例模式
//枚举实现单例(推荐)
public enum SingleTon {
MAYUN;
private String anotherFiled;
SingleTon(){
anotherFiled="mayun";
}
public String getAnotherField(){
return anotherFiled;
}
}