单例模式,也叫单子模式,是一种常用的软件设计模式。 在应用这个模式时,单例对象的类必须保证只有一个实例存在。 许多时候整个系统只需要拥有一个的全局对象,这样有利于我们协调系统整体的行为。
单例模式分为两种:
-
饿汉式
-
懒汉式
饿汉式
饿汉式单例指的是单例对象在类装载的时候进行构建,一旦完成加载,就把单例初始化完成,getInstance时已存在
饿汉式单例是线程安全的
构建方式:
-
将类的构造函数设置为私有的(private)
-
定义私有的静态成员变量,并进行实例化
-
定义公有的静态的getInstance() 方法 返回 单例对象
代码:
public class Singleton {
//1.实例化一个单例对象
private static Singleton singleton = new Singleton();
//2.对外屏蔽 new方式创建对象
private Singleton(){}
//3.公开获取对象的方法
public static Singleton getInstance(){
return singleton;
}
}
懒汉式
懒汉式单例是指单例对象在第一次使用的时候才进行构建
懒汉式单例是线程不安全的,所以在创建单例对象的时候需要进行线程同步
构建方式:
-
将类的构造函数设置为私有的(private)
-
定义私有的静态成员变量
-
定义公有的静态的getInstance() 方法,同步线程,实例化对象,返回单例对象
代码:
public class Singleton {
private static Singleton singleton;
private Singleton(){}
//由于是线程不安全的,要用synchronized进行线程同步
public static synchronized Singleton getInstance(){
if(singleton==null){
singleton = new Singleton();
}
return singleton;
}
}
除了懒汉式和饿汉式,单例模式还有一种“延时加载”的实现方式,这种方式在单例类中定义一个静态内部类,通过外部类的getInstance方法调用内部类中的静态成员变量获取单例对象。
静态内部类在Java语言中是一个很特殊的类,跟普通的静态类以及非静态的内部类都有很大的差异。
因为Java机制规定,内部类Holder只有在getInstance()方法第一次调用的时候才会被加载(实现了lazy)。
这种方式也是线程安全的。如果对资源使用十分在意可考虑使用,个人比较推荐使用这种。
public class Singleton {
private Singleton(){}
private static class Holder{
private static Singleton singleton = new Singleton();
}
public static Singleton getInstance(){
return Holder.singleton;
}
}