单例模式适用于要求某个类在整个系统中只能有一个实例对象可被获取,代表JVM运行环境的Runtime类,这种设计模式有几个特点:1、构造器私有化 2、含有一个该类的静态变量来保存这个唯一的实例 3、可向外提供该实例对象
共有三种写法:
第一种(饿汉式)
不存在线程安全问题因为类加载只加载一次
方式一:直接实例化
构造器私有化
自行创建并且用静态变量保存
向外提供这个实例
用final强调这个是一个单例
不管你是否需要这个对象,譬如只需该类的某一个静态方法,却也无可奈何要创建该实例
public class Singleton1{
public static final INSTANCE = new Singleton1();
private Singleton1(){
}
}
方式二:枚举
public enum Singleton1{
INSTANCE
}
方式三:静态代码块
public class Singleton1{
public static final INSTANCE;
static{
INSTANCE = new Singleton1();
//或者方法重载带参数,且参数需要从外部获取,比如配置文件,
//这种方式就比较适合
}
private Singleton1(){
}
private Singleton1(String info){
}
}
第二种(懒汉式)延迟创建这个实例对象
方式一线程不安全,适用于单线程
public class Singleton1{
private static final instance ;
private Singleton1(){
}
public static Singleton1 getInstance (){
if(instance == null){//这个if判断会导致线程不安全
instance = new Singleton1();
}
return instance;
}
}
方式二线程安全,适用于多线程
public class Singleton1{
private static final instance ;
private Singleton1(){
}
public static Singleton1 getInstance (){
synchronized(Singleton1.class){
if(instance == null){//这个if判断会导致线程不安全
instance = new Singleton1();
}
}
return instance;
}
}
这个还能改进,因为只有还没创建实例时需要去用同步锁防止有多个对象实例产生,而当有了第一个实例之后就可以不用进行同步锁了,所以再加个判断条件就行
public class Singleton1{
private static final instance ;
private Singleton1(){
}
public static Singleton1 getInstance (){
if(instance == null){
synchronized(Singleton1.class){
if(instance == null){//这个if判断会导致线程不安全
instance = new Singleton1();
}
}
}
return instance;
}
}
方式三 静态内部类
内部类被加载和初始化时才会去创建INSTANCE对象
静态内部类不会随着外部类的加载和初始化而初始化,他是要去单独加载和初始化的
因此是线程安全的
public class Singleton1{
private Singleton1(){}
private static class Inner{
private static final Singleton1 INSTANCE = new Singleton1();
}
public static Singleton1 getInstance(){
return Inner.INSTANCE;
}
}