单例模式
3个要点:私有的静态成员变量;私有的构造函数;公开的获取单例的静态方法
懒汉式
在需要使用到的时候才创建,所以被称之为懒汉式。
示例代码如下:
public class Singleton {
// 懒汉式
private static Singleton singleton = null;
// 私有构造函数
private Singleton() {<!-- -->}
public static Singleton getInstance(){<!-- -->
if (singleton == null){<!-- -->
singleton = new Singleton();
}
return singleton;
}
public static void main(String[] args) {<!-- -->
Singleton singleton1 = Singleton.getInstance();
Singleton singleton2 = Singleton.getInstance();
// 测试代码
if (singleton1 == singleton2){<!-- -->
System.out.println("singleton1 == singleton2");
}
}
}
输出:singleton1 == singleton2
存在的问题: 当多个线程同时调用getInstance时,不一定能够保证单例;
改进:
对方法加锁:
public class Singleton {
// 懒汉式 对方法加锁
private static Singleton singleton = null;
// 私有构造函数
private Singleton() {<!-- -->}
// 使用synchronized 关键字对方法进行加锁,确保任意时刻只有一个线程可执行该方法
synchronized public static Singleton getInstance() {<!-- -->
if (singleton == null) {<!-- -->
singleton = new Singleton();
}
return singleton;
}
public static void main(String[] args) {<!-- -->
Singleton singleton1 = Singleton.getInstance();
Singleton singleton2 = Singleton.getInstance();
if (singleton1 == singleton2) {<!-- -->
System.out.println("singleton1 == singleton2");
}
}
}
虽然解决了上述存在单例“不唯一”的问题,但是在多线程高并发访问环境中会导致系统性能大大降低
进一步改进:
无需锁方法,锁 singleton = new Singleton(); 这句代码即可。
public class Singleton {
// 懒汉式
// volatile 关键字会屏蔽Java虚拟机所做的一些代码优化
private volatile static Singleton singleton = null;
// 私有构造函数
private Singleton() {<!-- -->}
// 锁代码
public static Singleton getInstance() {<!-- -->
if (singleton == null) {<!-- -->
synchronized (Singleton.class){<!-- -->
if (singleton == null){<!-- --> // 双重判断
singleton = new Singleton();
}
}
}
return singleton;
}
public static void main(String[] args) {<!-- -->
Singleton singleton1 = Singleton.getInstance();
Singleton singleton2 = Singleton.getInstance();
if (singleton1 == singleton2) {<!-- -->
System.out.println("singleton1 == singleton2");
}
}
}
饿汉式
public class EagerSingleton {
private static final EagerSingleton instance = new EagerSingleton();
// 私有构造函数
private EagerSingleton(){
}
public static EagerSingleton getInstance(){<!-- -->
return instance;
}
}
优点: 简单、线程安全
缺点:类加载时就会生成对象,浪费资源
静态内部类
java特性
public class Singleton {
private Singleton() {<!-- -->
}
private static class HolderClass {<!-- -->
private static final Singleton singleton = new Singleton();
}
public static Singleton getInstance(){<!-- -->
// System.out.println("静态内部类创建");
return HolderClass.singleton;
}
}
作者:答学网,转载请注明原文链接:http://www.dxzl8.com/