zoukankan      html  css  js  c++  java
  • java之设计模式-单例模式

    1.定义:指一个类只有一个实例,且该类能自行创建这个实例的一种模式。例如,Windows只能打开一个任务管理器,这样可以避免因打开多个任务管理器窗口而造成内存资源的浪费,或出现各个窗口显示内容不一致等错误。

    例如:windows的回收站,操作系统中的文件系统,多线程中的线程池,打印机的后台处理服务,应用程序的日志对象,数据库的连接池,网站的计数器,web应用的配置对象,应用程序的对话框?

    单例模式的特点:

    a.单例类只有一个实例对象;

    b.该单例对象必须由单例类自行创建;

    c.单例类对外提供一个访问该单例的全局访问点。

    2.单例模式的结构与实现

      单例模式是设计模式中最简单的模式之一,通常,普通类的构造函数是共公有的,外部类可以通过“new 构造函数()”来生成多个实例。但是,如果将类的构造函数设为私有的,外部类就无法调用该构造函数,也就无法生成多个实例。这时该类自身必须定义一个静态私有实例,并向外提供一个静态的共有函数用于创建或获取该静态私有实例。

    2.1 单例模式的结构

      单例模式的主要角色如下:

     2.2 单例模式的实现方式

    步骤其实都是3步:

    1.首先他不能被外部类实例化,所以构造方法必须用private关键字,第一步就是先写一个私有的构造方法。

    private Singleton(){  };

    2.因为只能自己实例化自己,所以,要自己创建一个对象。以下哪个都可以,一个属于懒汉式,一个属于饿汉式。

    private static Singleton instance;    //懒汉式

    private static HungrySingleton instance = new Singleton();   //饿汉式

    3.要想外部访问到这个对象,那么必须定义一个public方法,这样把自己创建的对象传进去,让外部类使用才可以。

    public static Singleton getInstance()

      { return instance; }

    第一种,懒汉:该模式的特点是因为比较懒,类加载时没有生成单例,只有当第一次调用getInstance方法时才去创建这个单例。代码如下:

    线程不安全的:因为没有加锁 synchronized,所以严格意义上它并不算单例模式。
    这种方式 lazy loading 很明显,不要求线程安全,在多线程不能正常工作。
    public class LazySingleton { private LazySingleton(){ } private static LazySingleton instance; public static LazySingleton getInstance(){ if(instance == null){ instance = new LazySingleton(); } return instance; } }
    描述:这种方式具备很好的 lazy loading,能够在多线程中很好的工作,但是,效率很低,99% 情况下不需要同步。
    优点:第一次调用才初始化,避免内存浪费。
    缺点:必须加锁 synchronized 才能保证单例,但加锁会影响效率。
    getInstance() 的性能对应用程序不是很关键(该方法使用不太频繁)。
    
    public class Singleton {  
        private static Singleton instance;  
        private Singleton (){}  
        public static synchronized Singleton getInstance() {  
        if (instance == null) {  
            instance = new Singleton();  
        }  
        return instance;  
        }  
    }

    第二种,饿汉式:直接创建对象,不管你有没有用,反正提前创建好了。就和怕饿着一样,先准备好吃的再说。

    public class HungrySingleton {
        private HungrySingleton(){
        }
    
        private static HungrySingleton instance = new HungrySingleton();
    
        public static HungrySingleton getInstance(){
            return instance;
        }
    }

    测试以上的是不是同一个对象:结果显示对象地址都一样,是同一个。

    import org.testng.annotations.Test;
    
    public class TestModel {
        @Test
        public  void test() {
            HungrySingleton hungrySingleton = HungrySingleton.getInstance();
            HungrySingleton hungrySingleton1 = HungrySingleton.getInstance();
            System.out.println(hungrySingleton);
            System.out.println(hungrySingleton1);
            System.out.println(hungrySingleton == hungrySingleton1);
            assert hungrySingleton == hungrySingleton1;
    
        }
    
        @Test
        public  void test1() {
            LazySingleton lazySingleton = LazySingleton.getInstance();
            LazySingleton lazySingleton1 = LazySingleton.getInstance();
            System.out.println(lazySingleton);
            System.out.println(lazySingleton1);
            System.out.println(lazySingleton == lazySingleton1);
            assert lazySingleton == lazySingleton1;
    
        }
    }

    第三种:双检锁/双重校验锁(DCL,即 double-checked locking)

    描述:这种方式采用双锁机制,安全且在多线程情况下能保持高性能。
    getInstance() 的性能对应用程序很关键。
    
    public class Singleton {  
        private volatile static Singleton singleton;  
        private Singleton (){}  
        public static Singleton getSingleton() {  
        if (singleton == null) {  
            synchronized (Singleton.class) {  
            if (singleton == null) {  
                singleton = new Singleton();  
            }  
            }  
        }  
        return singleton;  
        }  
    }

    其他的参考:https://www.runoob.com/design-pattern/singleton-pattern.html

  • 相关阅读:
    linux系统分析工具续-SystemTap和火焰图(Flame Graph)
    如何使用strace+pstack利器分析程序性能
    MySQL数据类型-decimal详解
    服务器端数据合法性验证:签名sign和口令token原理
    linux系统下php通过php_oci8扩展连接oracle数据库 Nginx
    redis开启远程访问
    cURL函数库错误码说明之PHP curl_errno函数
    权限控制相关模块
    otool
    路由器
  • 原文地址:https://www.cnblogs.com/peiminer/p/13638173.html
Copyright © 2011-2022 走看看