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();
    }

    }
    }

  • 相关阅读:
    hdu1150&&POJ1325 Machine Schedule---最小点覆盖
    hdu-1068&&POJ1466 Girls and Boys---最大独立集
    hdu-2680 Choose the best route---dijkstra+反向存图或者建立超级源点
    hdu-1317 XYZZY---Floyd判连通+bellman最短路
    hdu-1874 畅通工程续---模板题
    hdu-2112 HDU Today---dijkstra+标号
    hdu-2066 一个人的旅行---模板题
    hdu-3790 最短路径问题---dijkstra两重权值
    hdu-2544 最短路---模板题
    BZOJ3529: [Sdoi2014]数表
  • 原文地址:https://www.cnblogs.com/erma0-007/p/8621332.html
Copyright © 2011-2022 走看看