单例模式
1.饿汉模式
类加载的时候就实例化,这种不管用没用到都首先实例化,可能会造成内存浪费
class Singleton {
//1. 构造器私有化, 外部能new
private Singleton() {
}
//2.本类内部创建对象实例
private final static Singleton instance = new Singleton();
//3. 提供一个公有的静态方法,返回实例对象
public static Singleton getInstance() {
return instance;
}
}
或者
class Singleton {
//1. 构造器私有化, 外部能new
private Singleton() {
}
//2.本类内部创建对象实例
private static Singleton instance;
static { // 在静态代码块中,创建单例对象
instance = new Singleton();
}
//3. 提供一个公有的静态方法,返回实例对象
public static Singleton getInstance() {
return instance;
}
}
2.懒汉
第一种在解决了内存浪费大的问题,需要用到时候才加载,但容易造成多个实例的问题,线程不安全
class Singleton {
private static Singleton instance;
private Singleton() {}
//提供一个静态的公有方法,当使用到该方法时,才去创建 instance
//即懒汉式
public static Singleton getInstance() {
// 这里容易造成线程不安全
// 如果一个线程执行到这里,另一个线程也到了这里,第一个线程还未执行接下来的另一个又执行了就会产生多个实例
if(instance == null) {
instance = new Singleton();
}
return instance;
}
}
解决线程安全问题,但是很费劲,
// 懒汉式(线程安全,同步方法)
class Singleton {
private static Singleton instance;
private Singleton() {}
//提供一个静态的公有方法,加入同步处理的代码,解决线程安全问题
//即懒汉式
public static synchronized Singleton getInstance() {
if(instance == null) {
instance = new Singleton();
}
return instance;
}
}
最佳
class Singleton {
private static volatile Singleton instance;
private Singleton() {}
//提供一个静态的公有方法,加入双重检查代码,解决线程安全问题, 同时解决懒加载问题
//同时保证了效率, 推荐使用
public static synchronized Singleton getInstance() {
if(instance == null) {
synchronized (Singleton.class) {
if(instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
单例使用场景
当一个对象需要频繁创建而且消耗资源比较多的时候,可以使用单例,比如工具类,数据库连接这些