核心作用:保证一个类只能创建一个对象。
优点:由于单例只生成一个实例对象,减小了系统性能开销,当一个对象的产生需要比较多的资源时,如读取配置,产生其他依赖对象时,则可以在应用启动时直接产生一个单例对象,然后永久驻留内存的方式解决。
单例模式可以在系统产生一个全局访问点,优化环境资源共享访问,例如可以设计一个单例表,负责所有数据表的映射处理。
五种单例模式:
主要两种
1,饿汉式:线程安全,调用效率高,但是不能延时加载
public class Singleton01 {
private static final Singleton01 instance = new Singleton01();
private Singleton01(){}
public static Singleton01 getInstance(){
return instance;
}
}
需要注意在代码中需要私有化该类的构造器,并且在类的初始化过程中就有了定义初始化,只需要调用getinstance()就能直接创建了。
饿汉式会保证static在类装载的时候类装载的时候初始化,此时不会涉及线程访问对象的问题,并且虚拟机只会装载一次该类,肯定不会发生并发访问的问题了,因此不需要使用sychronized关键字。
问题:如果出现,在程序中从来没有访问过getinstance()方法,会导致系统资源的浪费。
2,懒汉式:线程安全,调用效率不高,但是可以延时加载
//懒汉式实现
public class Singleton {
// 私有静态变量,用于保存唯一的实例
private static volatile Singleton instance;
// 私有构造方法,防止外部实例化
private Singleton() {
// 可以进行一些初始化操作
}
// 公有静态方法,获取唯一的实例
public static Singleton getInstance() {
// 双重检查锁定
if (instance == null) {
synchronized (Singleton.class) {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
// 其他方法(可根据需要添加)
public void doSomething() {
// 实例方法的具体实现
}
}
能够解决上面出现可能会导致的资源浪费的问题,在懒汉是实现的时候,首先定义instance,但是不会创建,直到在调用getinstance()方法才会创建了一个单例对象。在此代码中,虽然资源利用率提高了,但是并发效率降低了。
其余
3,静态内部类
实际上也是一种懒加载方法,不同的是:
(1)外部没有像懒加载方式的static属性,所以不会立即加载对象;
(2)只有真正调用getinstance()方法的时候才会加载静态内部类,加载的时候线程是安全的,instance是static final类型,保证了内存只有这样一个实例,而且只能加载一次,保证了线程安全。
(3)兼备了并发高效调用和延迟加载的特性
public class Singleton03{
private static class Singleton03ClassInstance{
private static final Singleton03 instance = new Singleton03();
}
public static Singleton03 getInstance(){
return Singleton03ClassInstance.instance;
}
private Singleton03(){}
}
4,枚举类型
优点:实现简单,枚举本身就是单例模式,在JVM的根本上提供了保障,避免通过反射和反序列化的漏洞。
缺点:无延迟加载
public enum Singleton05{
INSTANCE;
public void operation(){
System.out.println("枚举单例模式操作");
}
}