Java单例模式学习笔记

 

Singleton 模式的宗旨在于确保某个类只有一个实例,别且为之提供一个全局访问点。为了防止其他工作人员实例化我们的类,

可以为该类创建唯一一个构造器,并将构造器的可见设置为私有。值得注意的是,如果我们创建了其他的非私有的构造器,或者根本没有为该类提

供构造器,那么其他人员还是能实例化我们的类。 如果不希望提前创建单例对象,我们可以等到第一次使用该单例对象的时候在创建它,即

滞后初始化。滞后初始化单例对象有两个理由:

1.也许在静态初始化时间,你没有关于如何初始化单例对象的足够信息。

2.选择滞后初始化单例的目的也许为了等待资源,诸如数据库连接,尤其是在某些特定会话中不需要这个单例的应用程序中。

如果在多线程环境中对单例采用滞后初始化,那么我们必须小心防止多个线程同时初始化该

通常单例模式在Java语言中,有两种构建方式:

懒汉方式:指全局的单例实例在第一次被使用时构建。延迟初始化。

饿汉方式:指全局的单例实例在类装载时构建。 急切初始化。

1,饿汉式单例类


  1. public class Singleton1 {  
  2.       
  3.     private Singleton1() {  
  4.     }  
  5.     // 在自己内部定义自己一个实例.  
  6.     // 注意这是private 只供内部调用  
  7.  
  8.     private static Singleton1 instance = new Singleton1();  
  9.  
  10.     /** *//**  
  11.      *  这里提供了一个供外部访问本class的静态方法,可以直接访问  
  12.      * @return  
  13.      */ 
  14.     public static Singleton1 getInstance() {  
  15.         return instance;  
  16.     }  

2,懒汉式单例类


  1. public class Singleton2 {  
  2.  private Singleton1() {  
  3.     }  
  4.  
  5.     private static Singleton2 instance = null;  
  6.     /** *//**  
  7.  
  8.      * @return  
  9.      */ 
  10.     public static  Singleton2 getInstance() {      
  11.         if (instance == null)  
  12.             instance = new Singleton2();  
  13.         return instance;  
  14.     }  
  15. 下面主要多线程问题,在懒汉单例中,单线程是没有问题的,但多线程时就会有可能出现两个或者以上的Singletion2实例的情况。

    例如:线程1在判断instance==null为真,扫行new操作时,在执行new操作之前,判断为真之后,线程2正好执行判断操作,这时instance还为null.因此,线程2也会执行new操作。以此类推,在高并发下面,Singletion2的实例会总是变化。显然,这是不正确的。

    因此改变代码如下:

    
    
    1. public class Singleton3 {  
    2.  
    3.  private Singleton1() {  
    4.     }  
    5.     private static Singleton3 instance = null;  
    6.     /** *//**  
    7.      * 这个方法比上面有所改进,不用每次都进行生成对象,只是第一次   
    8.      * 使用时生成实例,提高了效率!  
    9.      * 为了多线程不出错,加入了同步标志  
    10.      * @return  
    11.      */ 
    12.     public static synchronized  Singleton3 getInstance() {      
    13.         if (instance == null)  
    14.             instance = new Singleton3();  
    15.         return instance;  
    16.     }  
    17.  

    但这样又产生了一个问题,每次获取实例时方法都是同步的,显然性能很受影响的,所以继续更改代码如下:

    1. public class Singleton4 {  
    2.    private static volatile Singleton4 instance;  
    3.     /** *//**
    4.  private Singleton1() {  
    5.     }  
    6.  
    7.      * 双重加锁实现多线程运用和性能优化  
    8.      * @return  
    9.      */ 
    10.     public static Singleton4 getInstance()  
    11.     {  
    12.       if (instance == null)  
    13.       {  
    14.         synchronized(Singleton4.class) {  //1  
    15.           if (instance == null)          //2  
    16.             instance = new Singleton4();  //3  
    17.         }  
    18.       }  
    19.       return instance;  
    20.     }  
    21. }  

你可能感兴趣的:(java基础篇,java,多线程,null,性能优化,数据库,class)