zoukankan      html  css  js  c++  java
  • 五种单例模式:

    package singleton;


    /***
    * 设计模式:一种套路,一种经验总结.
    * 单例模式:
    * 1)属于一种创建型模式(与对象创建相关)
    * 2)是为了保证类的对象在内存中的全局唯一性,给定
    * 的一种设计规则.
    * 单例模式应用场景:
    * 1)池对象的应用(例如字符串池)
    * 2)资源访问对象
    * 单例模式应用的目的:(减少对象对资源占用)
    * 单例模式的具体实现思路?
    * 规则:
    * 1)类的外部不允许直接构建此类对象
    * 2)类的外部只能通过静态方法访问此对象
    * 实现:
    * 1)构造方法私有化
    * 2)在类的内部构建对象
    * 3)定义一个静态方法,通过这个方法直接返回此对象

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

    */
    //单例设计方案1
    class Singleton01{
    private Singleton01(){}
    private static Singleton01 instance;
    public static Singleton01 getInstance(){
    if(instance==null){
    instance=new Singleton01();
    }
    return instance;
    }
    }
    //以上单例设计可能存在什么问题?(线程安全问题)

    Singleton通过将构造方法限定为private避免了类在外部被实例化,在同一个虚拟机范围内,Singleton的唯一实例只能通过getInstance()方法访问。

    (事实上,通过Java反射机制是能够实例化构造方法为private的类的,那基本上会使所有的Java单例实现失效。此问题在此处不做讨论,姑且掩耳盗铃地认为反射机制不存在。)

    但是以上懒汉式单例的实现没有考虑线程安全问题,它是线程不安全的,并发环境下很可能出现多个Singleton实例,要实现线程安全,有以下三种方式,都是对getInstance这个方法改造,保证了懒汉式单例的线程安全,如果你第一次接触单例模式,对线程安全不是很了解,可以先跳过下面这三小条,去看饿汉式单例,等看完后面再回头考虑线程安全的问题:


    //单例设计方案2(线程安全单例)
    class Singleton02{
    private Singleton02(){}
    private static Singleton02 instance;
    public static synchronized Singleton02 getInstance(){
    if(instance==null){
    instance=new Singleton02();
    }
    return instance;
    }
    }
    //以上单例设计存在什么问题吗?(性能问题)
    //单例设计方案3(线程安全+效率)
    class Singleton03{//大对象,稀少用
    private Singleton03(){}
    private static Singleton03 instance;
    public static Singleton03 getInstance(){
    if(instance==null){
    synchronized (Singleton03.class) {
    if(instance==null){
    instance=new Singleton03();
    }
    }
    }
    return instance;
    }
    }
    //以上设计适合对instance对象的频繁访问吗?不适合

    //单例设计方案四(小对象频繁用)
    class Singleton04{
    //private int[] array=new int[1024];
    private Singleton04(){}
    /**类加载时创建*/
    private static final Singleton04 instance=
    new Singleton04();
    /**此方法中因为没有阻塞问题所以适合频繁访问*/
    public static Singleton04 getInstance() {
    return instance;
    }
    //public static void display(){}
    //public void show(){}
    }
    //请问以上设计存在什么问题吗?(假如对象比较大,
    //类加载时就创建了此对象,假如不使用,就可能长时间占用资源)
    //单例设计方案五(采用延迟加载策略优化设计方案四)
    class Singleton05{
    private Singleton05(){}
    static class Lazy{//类何时被加载?
    public static final Singleton05
    instance=new Singleton05();
    }
    public static Singleton05 getInstance(){
    //何时需要何时加载
    return Lazy.instance;
    }
    //请问访问Singleton05类的这个方法时候会加载Lazy吗?

    //public static void display(){}//不会,这是静态方法,加载类时不会加载Lazy
    //请问访问Singleton05类的show方法时是否需要加载Lazy?
    //public void show(){}//会,这是实例方法,创建实例对象时会加载Lazy
    }
    //---------------------------------------------

    public class TestSingleton {

    public static void main(String[] args) {

    for(int i=0;i<5;i++){
    new Thread(){
    public void run() {
    System.out.println(
    Singleton01.getInstance()
    );
    };
    }.start();
    }

    }
    }

  • 相关阅读:
    suse12安装详解
    Centos7上部署openstack mitaka配置详解(将疑难点都进行划分)
    菜鸟帮你跳过openstack配置过程中的坑[文末新添加福利]
    openstack中dashboard页面RuntimeError: Unable to create a new session key. It is likely that the cache is unavailable.
    Multiple network matches found for name 'selfservice', use an ID to be more specific.报错
    查看 SELinux状态及关闭SELinux
    SELinux深入理解
    IP地址、子网掩码、网络号、主机号、网络地址、主机地址
    Oracle job procedure 存储过程定时任务
    POI文件导出至EXCEL,并弹出下载框
  • 原文地址:https://www.cnblogs.com/erma0-007/p/8621332.html
Copyright © 2011-2022 走看看