Java设计模式之详细介绍Java设计模式----单例模式

单例模式是一种常见的编程设计模式,确保一个类只有一个实例并提供全局访问点。本文详细介绍了单例模式的概念、作用以及多种实现方式,包括懒汉、饿汉、双重锁和静态内部类等,还提到了枚举实现单例的优点,如线程安全和防止反序列化创建新对象。
摘要由CSDN通过智能技术生成

参考文章

1.单例模式介绍

  • 单例模式(Singleton Pattern)是java中最简单的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。
  • 这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建,这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。
  • 注意:
    • 单例类只能有一个实例
    • 单例类必须自己创建自己的唯一实例
    • 单例类必须给所有其他对象提供这一实例

2.为什么要使用单例模式?

  • 看下面这段代码
public class Printer{
	//创建私有的全局变量
	private static Printer printer = null;
	//构造方法私有化,保证在系统的使用中,只有一个实例
	private Printer(){
	
	}
	//如果有多个线程并发访问时,上锁,让其排队等候,一次只能一个人用
	public static synchronized Printer getInstance(){
		//如果为空,创建本实例
		if(printer == null){
			printer = new Printer();
		}
			return printer;
	}
}
  • 上面这段代码,是单例模式中的懒汉方式实现,首先向外提供了一个可被访问的实例化的对象,如果没有此对象,那么创建一个返回,并且在遇到多线程并发访问时,加上关键字synchronized,上锁,让没有持有该对象的类处于等待状态,当前持有该printer的线程任务结束之后,处于等待中的线程才能逐个去持有该实例,去操作其方法。这样的一个过程在编程中称为单例模式。
  • 我们可以想想,如果在系统中不使用单例模式的化,在遇到多线程访问的时候,printer就会给要请求的类分别在内存中new出一个printer对象,让这些请求的类去做print方法,这样大量占有内存,就会导致系统运行变慢,所以这个时候,单例模式就出现了。
  • **意图:**保证一个类仅有一个实例,并提供一个访问它的全局访问点
  • **主要解决:**一个全局使用的类频繁的创建与销毁
  • **何时使用:**当你想控制实例的数目,节省系统的资源的时候
  • **关键代码:**构造函数私有化
  • 应用实例:
    • 一个党只能有一个书记
    • windows是多进程多线程的,在操作一个文件的时候,就不可避免的出现多个进程或线程操作一个文件的现象,所以所有的文件处理就必须通过唯一的实例来进行
    • 一些设备管理器常常设计为单例模式,比如一个电脑有两台打印机,在输出的时候就要处理不能两台打印机打印同一个文件。
  • 优点:
    • 在内存中只有一个实例,减少了内存的开销,尤其是频繁的创建和销毁实例
    • 避免对资源的多重占用
  • 缺点:
    • 没有接口,不能继承,与单一职责原则冲突,一个类应该只关心内部逻辑,而不关心外面怎么样来实例化

3.单例模式的实现

1.懒汉写法

public class Singleton {

  private static Singleton singleton;

  private Singleton() {
  }

  public static Singleton getInstance() {
   if (singleton == null) {
    singleton = new Singleton();
   }
   return singleton;
  }
}
  • 上面的写法是不是线程安全的,下面这个是
public class Singleton {
//很懒,用的时候再进行加载
   private static Singleton instance;
   private Singleton (){}
   public static synchronized Singleton getInstance() {
   if (instance == null) {
       instance = new Singleton();
   }
   return instance;
   }
}

2.饿汉写法

//很饿很着急,在类加载的时候就创建实例对象
public class Singleton {
   private static Singleton instance = new Singleton();
   private Singleton (){}
   public static Singleton getInstance() {
   return instance;
   }
}

3. 双重锁写法(是懒汉模式的升级版) 进行双重判断,当已经创建过实例对象后就无需加锁,提高效率,也是一种推荐的使用方式

public class Single{
    private Single(){
        
    }
    private volatile static Single single;
    
    public static Single getInstance(){
        if(single == null){
            synchronized(Single.class){
                if(single == null){
                    single = new Single();
                }
            }
        }
        return single;
    }
}

4.静态内部类写法

public class Singleton{
    privite static class SingletonHolder{
        private static final Singleton INSTANCE = new  Singleton();
    }
    private Singleton(){}
    public static final Singleton getInstance(){
        return SingletonHolder.INSTANCE;
    }
}

5. 枚举写法(是effective java中的推荐写法,它不仅可以避免多线程的同步问题,还可以防止反序列化重新创建新的对象)

public enum Singleton{
    INSTANCE;
    public void whateverMethod(){
        
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值