开发者社区> 兴化> 正文
阿里云
为了无法计算的价值
打开APP
阿里云APP内打开

设计模式-12-单例模式

简介: 单例模式(Singleton Pattern)负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。也属于创建型模式。
+关注继续查看

单例模式(Singleton Pattern)负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。也属于创建型模式。

直接代码实现:

一、饿汉式

package com.xing.design.singleton;


/**

*  单例模式

* @author xing

*/

public class SingletonObj {

//创建 SingletonObj 的一个对象

private static SingletonObj instance = new SingletonObj();

//构造方法私有化

private SingletonObj(){}

//对外提供访问入口,因为关闭了构造方法,所以只能从这个入口访问本类对象

public static SingletonObj getInstance(){

return instance;

 }

//写个方法用来调用

public void test() {

   System.out.println("单例模式实例化对象的测试方法。。。");

 }

}


测试:

package com.xing.design.singleton;


public class SingletonDemo {

public static void main(String[] args) {

   SingletonObj singletonObj1 = SingletonObj.getInstance();

   singletonObj1.test();

//再来一个对比下hashCode

   SingletonObj singletonObj2 = SingletonObj.getInstance();

   singletonObj2.test();

   System.out.println("singletonObj1=>"+singletonObj1.hashCode());

   System.out.println("singletonObj2=>"+singletonObj2.hashCode());

 }

}

结果:

图片

       可以看到两次获取的对象hashCode码一样,是同一个对象哈。

       上述这种写法是在类加载的时候就实例化了对象,这种写法叫饿汉式。但是如果这个对象一直没有用,就造成了内存浪费,没有达到懒加载(Lazy Loading)的效果。

我理解的懒汉式和饿汉式:

懒汉式是用的时候再实例化,饿了再做饭。或者有句话叫啥来着,想蹲坑了才修厕所呢,哈哈哈

饿汉式是先实例化,用的时候直接取用。就跟饿过的人一样,先把饭做好,饿了就能吃。

二、懒汉式

package com.xing.design.singleton;


/**

*  单例模式

* @author xing

*/

public class SingletonObj2 {

//创建 SingletonObj 的一个对象

private static SingletonObj2 instance;

//构造方法私有化

private SingletonObj2(){

   System.out.println("构造个SingletonObj2");

 }

//对外提供访问入口,因为关闭了构造方法,所以只能从这个入口访问本类对象

public static SingletonObj2 getInstance(){

if(instance == null) {

     instance = new SingletonObj2();

   }

return instance;

 }

public void test() {

   System.out.println("单例模式实例化对象的测试方法。。。");

 }

}


测试:

package com.xing.design.singleton;


public class SingletonDemo {

 public static void main(String[] args) {

   SingletonObj2 singletonObj21 = SingletonObj2.getInstance();

   singletonObj21.test();

//再来一个对比下hashCode

   SingletonObj2 singletonObj22 = SingletonObj2.getInstance();

   singletonObj22.test();

   System.out.println("singletonObj21=>"+singletonObj21.hashCode());

   System.out.println("singletonObj22=>"+singletonObj22.hashCode());

 }

}

结果:

图片

       这种写法起到了Lazy Loading的效果,不过main方法调用的时候都是第一次加载类哈,看不出来,不过倒是能看出来获取两个实例对象只调用过一次构造哈,更能说明单例模式多次返回的都是同一个对象。

三、双重检验管控的线程安全单例模式

package com.xing.design.singleton;


/**

* 懒汉模式-线程安全,适用于多线程

*/

public class SingletonObj3{

private static volatile SingletonObj3 safeSingleton;//防止指令重排

private SingletonObj3() {

     System.out.println("构造个SingletonObj3");

   }

public static SingletonObj3 getInstance(){

if(safeSingleton==null){

           synchronized (SingletonObj3.class){

if(safeSingleton==null){//双重检测

                   safeSingleton = new SingletonObj3();

               }

           }

       }

return safeSingleton;

   }

public void test() {

   System.out.println("单例模式实例化对象的测试方法。。。");

 }

}

       重排序是为了优化性能,但是不管怎么重排序,在单线程下一定能保证结果的正确性,但是在多线程环境下,可能发生重排序,影响结果。具体底层的我也不懂,以后再学吧。这里要禁用重排序,就用了volatile 关键字。


总结:

       单例模式只能由自己创建并始终只有一个实例化对象,核心代码是构造方法私有化、提供一个静态方法作为唯一访问入口。

       应用场景有:当前系统登录人数管理、Java的Runtime、线程池等频繁的创建和销毁对象的情况。


END

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
单例设计模式
单例设计模式
44 0
【设计模式】单例模式
设计模式 单例模式 单例模式(Singleton Pattern)是一种常用的软件设计模式。在它的核心结构中只包含一个被称为单例类的特殊类。
950 0
设计模式-单例模式
单例模式(Singleton Pattern) 什么是单例模式 一个对象只能有一个实例,所有对象对它的引用都指向同一个内存地址 示例代码如下 1. 懒汉式加载 public class Singleton { // 构造一个私有的构造器 p...
930 0
设计模式--单例模式
单例模式(singleton) 单例模式最初的定义出现于《设计模式》(Addison-Wesley,1994) 单例模式:保证一个类仅有一个实例,并提供一个访问它的全局访问点。
924 0
单例设计模式
饿汉式单例 对于饿汉模式,我们可这样理解:该单例类非常饿,迫切需要吃东西,所以它在类加载的时候就立即创建对象。 懒汉式单例类 对于懒汉模式,我们可以这样理解:该单例类非常懒,只有在自身需要的时候才会行动,从来不知道及早做好准备。
798 0
+关注
兴化
码中自由一片天地。。。
文章
问答
文章排行榜
最热
最新
相关电子书
更多
低代码开发师(初级)实战教程
立即下载
阿里巴巴DevOps 最佳实践手册
立即下载
冬季实战营第三期:MySQL数据库进阶实战
立即下载