单例模式(Singleton):保证一个类仅有一个实例,并提供一个访问它的全局访问点。
构造单例模式步骤:
1、将构造方法私有化,不允许外面直接创建。
2、声明唯一实例(private static)。
3、提供一个用于获取实例的方法(public static)。
单例模式分为饿汉模式和懒汉模式:
饿汉模式:实例在类加载的时候初始化。加载速度慢,运行获取速度快。线程安全。
懒汉模式:实例在类调用的时候初始化。加载速度快,运行获取对象慢。线程不安全。
/*
* 饿汉模式
* 类创建的时创建一个静态的对象
*/
public class Singleton1 {
// 声明私有化构造方法
private Singleton1() {
}
// 创建类的唯一实例,使用private static修饰
private static Singleton1 instance = new Singleton1();
// 提供获取实例的方法
public static Singleton1 getInstance() {
return instance;
}
}
/*
* 懒汉模式
* 类访问时创建对象
*/
public class Singleton2 {
private Singleton2() {
}
private static Singleton2 instance;
public static Singleton2 getInstance() {
if (instance == null) {
instance = new Singleton2();
}
return instance;
}
}
单例模式的线程安全
多线程的程序中,多个线程同时访问Singleton类,调用getInstance()方法,就会有可能造成创建多个实例。
三种多线程下线程安全的实例:
1、饿汉模式是线程安全的,其在类加载的时候直接new一个静态对象出来。
2、对getInstance方法加锁,确保每次只有一个线程执行该方法。
public class Singleton {
private static Singleton instance;
private Singleton (){
}
public static synchronized Singleton getInstance(){ //对获取实例的方法进行同步
if (instance == null)
instance = new Singleton();
return instance;
}
}
上述代码中的一次锁住了一个方法, 这个粒度有点大 ,改进就是只锁住其中的new语句就OK。就是所谓的“双重锁”机制。
3、使用双重锁定(Double-Check Locking)public class Singleton {
private static Singleton instance;
private Singleton (){
}
public static Singleton getInstance(){ //对获取实例的方法进行同步
if (instance == null){
synchronized(Singleton.class){
if (instance == null)
instance = new Singleton();
}
}
return instance;
}
}
该方法只是在实例未被创建的时候加锁处理,同时也能保证多线程安全。