设计模式之单例模式

实现方式

共三种:

  1. 饿汉式
  2. 懒汉式
  3. 枚举单例
  4. 静态内部类式 (推荐)

饿汉式

原理:类在初始化加载的时候,会加载内部 静态 成员对象,然后方法被调用的时候,直接返回这个对象
/**
* 测试饿汉式单例模式
* @author 尚学堂高淇 www.sxt.cn
*
*/
public class Demo {
    private Demo(){}; //私有化构造器
    private static Demo demo = new Demo();  //类初始化时,立即加载这个对象(没有延时加载的优势)。加载类时,天然的是线程安全的!
    public  static Demo getInstance(){     //方法没有同步,调用效率高!
        return demo;
    }
}

懒汉式

原理:方法被外部调用的时候,先判断对象是否被实例化,如果没有,则实例化返回,如果有 直接返回  该方法需要加同步锁synchronized,
/**
* 测试懒汉式单例模式
*/
public class Demo {
    private Demo(){};
    private static Demo demo;
    public  static synchronized Demo getInstance(){  //方法同步,调用效率低!
        if(demo == null){
            demo = new Demo();
        }
        return demo;
    }
}

枚举单例

优点:
    1.实现简单
    2.枚举本身就是单例模式。由JVM从根本上提供保障 避免通过反射和反序列化的漏洞
缺点:
    1.无延迟加载

/**
* 测试枚举式实现单例模式(没有延时加载)
*/
public enum SingletonDemo5 {
    
    //这个枚举元素,本身就是单例对象!
    INSTANCE;
    
    //添加自己需要的操作!
    public void singletonOperation(){
    }
}

静态内部类式 推荐

1.没有静态 内部 成员对象 所以和饿汉式不一样
2.静态内部类,在调用的时候初始化 懒
3.内部类中成员对象是 static final 保证了在内存中只有一份实例,


/**
* 测试静态内部类实现单例模式
* 这种方式:线程安全,调用效率高,并且实现了延时加载!
* @author 尚学堂高淇 www.sxt.cn
*
*/
public class Demo {

    private Demo(){};

    //静态内部类
    private static class DemoInstance {
        private static final Demo instance = new Demo();
    }

    public static Demo getInstance(){
        return DemoInstance.instance;
    }
}

比较

主要

  1. 饿汉式(线程安全,调用效率高,但是 不能延时加载)
  2. 懒汉式 (线程安全,调用效率不高,但是 可以延时加载) 每次调用getInstance() 方法都要同步,并发效率太低
  3. 静态内部类式(线程安全,调用效率高。可以延时加载)
  4. 枚举单例(线程安全,调用效率高,不能延时加载)

测试效率

/**
* 测试多线程环境下五种创建单例模式的效率
*/
public class Client3 {
    
    public static void main(String[] args) throws Exception {
        
        long start = System.currentTimeMillis();
        int threadNum = 10;
        final CountDownLatch  countDownLatch = new CountDownLatch(threadNum);
        
        for(int i=0;i<threadNum;i++){
            new Thread(new Runnable() {
                @Override
                public void run() {
                    
                    for(int i=0;i<1000000;i++){
//                      Object o = SingletonDemo4.getInstance();
                        Object o = SingletonDemo5.INSTANCE;
                    }
                    countDownLatch.countDown();
                }
            }).start();
        }
        
        countDownLatch.await();    //main线程阻塞,直到计数器变为0,才会继续往下执行!
        
        long end = System.currentTimeMillis();
        System.out.println("总耗时:"+(end-start));
    }
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值