• 设计模式-单例模式(Singleton Pattren)(饿汉模式和懒汉模式)


    单例模式(Singleton Pattren):确保一个类在整个应用中只有一个实例,并提供一个全局访问点。

    实现要点:

    1. 私有化构造方法

    2. 类的实例在类初始化的时候创建

    3. 提供一个类方法,返回值为类的实例,其他类调用该方法获取到该类的实例

    1. 常规实现(线程不安全,不考虑多线程):

     1 public class Singleton1 {
     2     private static Singleton1 instance;
     3 
     4     private Singleton1() {
     5 
     6     }
     7 
     8     public static Singleton1 getInstance() {
     9         if (instance == null) {
    10             instance = new Singleton1();
    11         }
    12         return instance;
    13     }
    14 }

    2. 线程安全懒加载实现(懒汉式):

     1 public class Singleton2 {
     2     private volatile static Singleton2 instance;
     4 
     5     private Singleton2() {
     6     }
     7 
     8     public Singleton2 getInstance() {
     9         if (instance == null) {
    10             synchronized (Singleton2.class) {
    11                 if (instance == null) {
    12                     instance = new Singleton2();
    13                 }
    14             }
    15         }
    16         return instance;
    17     }
    18 }

    3. 线程安全快速加载实现(饿汉式):

     1 public class Singleton3 {
     2     private static Singleton3 instance = new Singleton3();
     3 
     4     private Singleton3() {
     5     }
     6 
     7     public static Singleton3 getInstance() {
     8         return instance;
     9     }
    10 }

    三种实现方法中:

    第一种,假如在单线程模式下,是可以的,不会出现多个实例的情况,但是在多线程的模式下是不安全的,可能会创建多个实例。

    第二种,在方法内部进行了加锁操作,同时使用 volatile 修饰 instance,防止 Java 指令重排,确保当变量 instance 被初始化成 Singleton2 实例时,多个线程正确的处理 instance 变量。该写法只有在使用的时候才会初始化对象,可以提高性能。

    第三种,比较简单的写法,在类被加载的时候就初始化了对象,所以在调用的时候直接返回这个变量就可以了,线程安全由 JVM 来确保,因为 JVM 加载的时候是单线程的。不存在线程不安全的问题,但是该对象在类加载进 JVM 的时候就初始化了,会占用资源。

    一种更好的写法,弥补饿汉式初始化以后不使用对象占用资源的问题,弥补懒汉式初始化过程中使用 synchronized 影响性能的问题 

     1 public class Singleton4 {
     2 
     3     private Singleton4() {
     4     }
     5 
     6     private static class Holder {
     7         private static Singleton4 instance = new Singleton4();
     8     }
     9 
    10     public static Singleton4 getInstance() {
    11         return Holder.instance;
    12     }
    13 }

    由于静态单例对象没有作为Singleton的成员变量直接实例化,因此类加载时不会实例化Singleton,第一次调用getInstance()时将加载内部类HolderClass,在该内部类中定义了一个static类型的变量instance,此时会首先初始化这个成员变量,由Java虚拟机来保证其线程安全性,确保该成员变量只能初始化一次。由于getInstance()方法没有任何线程锁定,因此其性能不会造成任何影响。

     知识点: 可以写出三种单例模式,参考:《Effictive Java》单例模式的实现

    参考:http://blog.csdn.net/lovelion/article/details/7420888

  • 相关阅读:
    在DataGrid中创建一个点击列名时的弹出式窗口
    利用自定义事件实现不同窗体间的通讯 C#篇
    用javascript实现禁用鼠标右键
    刷新页面时,防止滚动条上滚
    web服务编程
    数据库链接Connection和DataReader的关闭
    .NET的WEB商业应用架构所要解决的若干
    zblog屏蔽分类文章
    过年随想
    mysql数据库文件的真实的物理存储位置
  • 原文地址:https://www.cnblogs.com/liyiran/p/6506900.html
Copyright © 2020-2023  润新知