关于单例模式的浅谈

来源:互联网 发布:马泰尔家族知乎 编辑:程序博客网 时间:2024/06/07 12:51

一般来说,提到设计模式,大家首先想到的就是单例模式。

那么我就简单的聊聊单例模式。既然有单例,那就也有多例


1.第一个问题什么是单例多例?

所谓单例模式就是所有的请求处理都是用一个对象来处理,每次只产生一个实例,比如开发中常用的service和dao层的对象通常都是单例的,

而多例则是每个请求都要产生一个新的对象去访问处理,比如action。通用SSH,单例在spring是默认的,对于struts2,action必须使用多例,

因为action本身有请求的值,即可变的状态。


2.第二个问题为什么要用单例多例?

之所以使用单例模式,是因为没有必要每个请求都创建一个对象,浪费内存

之所以使用多例模式,是因为防止并发问题,一个请求改变了对象的状态,此时对象又处理另一个请求,就导致了错误的发生


3.单例模式的特点

单例类只能有一个实例

单例类必须自己创建唯一的实例

单例类必须给其他对象提供这一实例


4.单例模式的应用

单例模式确保某个类只有一个实例,而且自行实例化并向整个系统提供这个实例。在计算机系统中,线程池、缓存、日志对象、对话框、打印机、显卡的驱动程序对象常被设计成单例。这些应用都或多或少具有资源管理器的功能。每台计算机可以有若干个打印机,但只能一个printer spooler,以避免两个打印作业同时输出到打印机中,每台计算机可以有若干个通信端口,系统应当集中管理这些通信端口,以避免一个通信端口同时被两个请求同时调用,总之,选择单例模式就是为了避免不一致状态,避免政多出头。


5.单例模式的实现方式

    第一种:懒汉模式(线程不安全)

  1. //懒汉式单例类.在第一次调用的时候实例化自己   
  2. public class Singleton {  
  3.     private Singleton() {}  
  4.     private static Singleton single=null;  
  5.     //静态工厂方法   
  6.     public static Singleton getInstance() {  
  7.          if (single == null) {    
  8.              single = new Singleton();  
  9.          }    
  10.         return single;  
  11.     }  


双重检查机制,保证线程安全

  1. public static Singleton getInstance() {  
  2.         if (singleton == null) {    
  3.             synchronized (Singleton.class) {    
  4.                if (singleton == null) {    
  5.                   singleton = new Singleton();   
  6.                }    
  7.             }    
  8.         }    
  9.         return singleton;   
  10.     }

静态内部类,既保证了安全又避免了同步带来的性能影响(推荐使用)

[java] view plain copy print?
  1. public class Singleton {    
  2.     private static class LazyHolder {    
  3.        private static final Singleton INSTANCE = new Singleton();    
  4.     }    
  5.     private Singleton (){}    
  6.     public static final Singleton getInstance() {    
  7.        return LazyHolder.INSTANCE;    
  8.     }    

第二种:饿汉式单例(线程安全)

[java] view plain copy print?
  1. //饿汉式单例类.在类初始化时,已经自行实例化   
  2. public class Singleton1 {  
  3.     private Singleton1() {}  
  4.     private static final Singleton1 single = new Singleton1();  
  5.     //静态工厂方法   
  6.     public static Singleton1 getInstance() {  
  7.         return single;  
  8.     }  
  9. }  

第三种:使用枚举(effective java 上推荐使用)

     public   enum  getInstance(){

ONE;

      }


饿汉式和懒汉式的区别:

1.饿汉式在类创建的同时实例化一个静态对象出来,不管之后使用不使用都会占据一定内存,线程是安全的

2.懒汉式在第一次使用改单例的时候才会实例化对象,线程不安全,一般推荐用静态内部类来初始化instance


什么是线程安全?

简单来说,就是你的代码所在的进程中多个线程在同时运行,而这些线程可能同时运行这段代码。如果每次运行结果和单线程运行结果一致,那就是线程安全的