java之单例模式

本文详细介绍了Java中的单例模式,包括其定义、应用场景、优缺点以及常见的实现方式,如饿汉式、懒汉式、静态内部类和枚举。此外,还探讨了解决线程安全问题的双重检测锁,并分析了如何通过反射和反序列化破坏单例,以及相应的防御措施。
摘要由CSDN通过智能技术生成

java之单例模式

什么是单例模式?

保证一个了类仅有一个实例,并提供一个访问它的全局访问点。

单例模式的应用场景?

1.网站的计数器,一般也是采用单例模式实现,否则难以同步;

2.Web应用的配置对象的读取,一般也应用单例模式,这个是由于配置文件是共享的资源;

3.数据库连接池的设计一般也是采用单例模式,因为数据库连接是一种数据库资源;

4.多线程的线程池的设计一般也是采用单例模式,这是由于线程池要方便对池中的线程进行控制。

单例的优缺点?

优点:

提供了对唯一实例的受控访问;
由于在系统内存中只存在一个对象,因此可以 节约系统资源,当 需要频繁创建和销毁的对象时单例模式无疑可以提高系统的性能;
避免对共享资源的多重占用

缺点:

不适用于变化的对象,如果同一类型的对象总是要在不同的用例场景发生变化,单例就会引起数据的错误,不能保存彼此的状态;
由于单利模式中没有抽象层,因此单例类的扩展有很大的困难;
单例类的职责过重,在一定程度上违背了“单一职责原则”。

单例的创建方式

1. 饿汉式

类初始化时,会立即加载该对象,线程安全,效率高。

/**
 * @Author 刘翊扬
 * @Version 1.0
 */
public class SingletonHungry {
   
 
    private static SingletonHungry instance = new SingletonHungry();
 
    private SingletonHungry() {
   }
 
    public static SingletonHungry getInstance() {
   
        return instance;
    }
}

验证:

public class Main {
   
    public static void main(String[] args) {
   
        SingletonHungry instance1 = SingletonHungry.getInstance();
        SingletonHungry instance2 = SingletonHungry.getInstance();
        System.out.println(instance1 == instance2);      // 结果是true
    }
}

优点:仅实例化一次,线程是安全的。获取实例的速度快

缺点:类加载的时候立即实例化对象,可能实例化的对象不会被使用,造成内存的浪费。

2. 使用静态代码块

**
* @author 刘翊扬
*/
public class HungrySingleton2 {
   
   
   private static HungrySingleton2 instance = null;
   
   private HungrySingleton2() {
   }
 
   static {
   
       instance = new HungrySingleton2();
   }
   
   private HungrySingleton2() {
   }
   
   public static HungrySingleton2 getInstance() {
   
       return instance;
   }
   
}

3. 懒汉式

public class SingletonLazy {
   
 
    private static SingletonLazy instance;
 
    private SingletonLazy() {
   }
 
    public static SingletonLazy getInstance() {
   
        if (instance == null) {
   
            instance = new SingletonLazy();
        }
        return instance;
    }
}

优点:在使用的时候,创建对象,节省系统资源

缺点

如果获取实例时,初始化的工作量较多,加载速度会变慢,影响系统系能

每次获取对象,都要进行非空检查,系统开销大

非线程安全,当有多个线程同时调用 getInstance()方法,时,会有线程安全问题,可能导致创建多个对象

4. 静态内部类

/**
* @Author 刘翊扬
* @Version 1.0
*/
public class SingletonDemo03 {
   
 
   private SingletonDemo03() {
   }
 
   public static class SingletonClassInstance {
   
       private static final SingletonDemo03 instance = new SingletonDemo03();
   }
 
   public static SingletonDemo03 getInstance() {
   
       return SingletonClassInstance.instance;
   }
}

优势:兼顾了懒汉模式的内存优化(使用时才初始化)以及饿汉模式的安全性(不会被反射入侵)。

劣势:需要两个类去做到这一点,虽然不会创建静态内部类的对象,但是其 Class 对象还是会被创建,而且是属于永久带的对象。

5. 使用枚举

枚举本身就是单例的,一般在项目中定义常量。
例如:

/**
 * @Author 刘翊扬
 * @Version 1.0
 */
public enum  ResultCode {
   
    
    SUCCESS(200, "SUCCESS"),
    ERROR(500, "ERROR");
    
    private Integer code;
    
    private String msg;
 
    ResultCode(Integer code, String msg
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值