单例模式实现的3种方式,推荐

以下为单例模式实现的3种常用方式。

(1)饿汉模式 

public class Hungry {
    private Hungry() { }//单例模式都要注意隐藏构造器
    private  static Hungry singleTon = new Hungry();

    public static Hungry getSingleTon(){
        return singleTon;
    }

    /*测试*/
    public static void main(String[] args){
        for(int i=0;i<10;i++){
            new Thread(new Runnable() {
                @Override
                public void run() {
                    System.out.println(Hungry.getSingleTon());
                }
            }).start();
        }
    }
}

执行结果:

com.bee.sample.ch1.practice.Hungry@64669643
com.bee.sample.ch1.practice.Hungry@64669643
com.bee.sample.ch1.practice.Hungry@64669643
... ...(忽略几行)

【点评】是线程安全的,但是系统启动,在类加载时,会直接new出一个对象,导致系统启动变慢。

(2)懒汉模式

public class SynDoubleCheckLazy {
    private SynDoubleCheckLazy(){}
    private static SynDoubleCheckLazy singleTon=null;
    public static SynDoubleCheckLazy getSingleTon(){
        if(singleTon==null){
            //这个Thread.sleep仅仅为测试多线程,制造障碍,使用时删去
            try{
                Thread.sleep(200);
            }catch (Exception e){
                e.printStackTrace();
            }
            synchronized (SynDoubleCheckLazy.class){
                if(singleTon==null){
                    singleTon=new SynDoubleCheckLazy();
                }
            }
        }
        return singleTon;
    }

    /*以下为测试*/
    public static void main(String[] args){
        for(int i=0;i<5;i++){
            new Thread(new Runnable() {
                @Override
                public void run() {
                    System.out.println(SynDoubleCheckLazy.getSingleTon());
                }
            }).start();
        }
    }
}

【点评】线程安全,且效率优良,值得推荐。两次判断getSingleTon 返回对象是否为空,第一次是效率需要,如果非空,直接返回,不用进入下面的同步模块损失效率,第二次是安全需要。

(3)私有静态内部类模式

package com.bee.sample.ch1.practice;

public class PrivateStaticInner {
    private PrivateStaticInner(){}
    private static class PrivateStaticInnerHolder{
        private static PrivateStaticInner singleTon = new PrivateStaticInner();
    }
    public static PrivateStaticInner getSingleTon(){
        return PrivateStaticInnerHolder.singleTon;
    }

    /*测试*/
    public static void main(String[] args){
        for(int i=0;i<5;i++){
            new Thread(new Runnable() {
                @Override
                public void run() {
                    System.out.println(PrivateStaticInner.getSingleTon());
                }
            }).start();
        }
    }
}

【点评】线程安全,外貌和饿汉模式相似,两者都是利用类加载的方式来实现初始化时只有一个线程,区别在于PrivateStaticInner 加载时,不会立刻实例化,而是调用getSingelTon方法时,才会装载内部类PrivateStaticInnerHolder,从而完成父类PrivateStaticInner 的实例化,值得推荐。

猜你喜欢

转载自blog.csdn.net/neymar_jr/article/details/81143662
今日推荐