• 首页

  • 归档

  • 分类

  • 标签

  • 喵星人

  • 心情

  • 关于
W e A r e F a m i l y ! m i a o ~
W e A r e F a m i l y ! m i a o ~

柴子

青春流逝,记录往昔

08月
19
设计模式

设计模式-单例

发表于 2021-08-19 • 字数统计 1885 • 被 174 人看爆

singleton (单例)

1. 饿汉式

/**
 * 饿汉式
 * 类加载到内存后,就实例化一个单例,JVM保证线程安全
 * 简单实用
 */
public class Singleton01 {

    private static final Singleton01 singleton = new Singleton01();

    private Singleton01() {
    }

    public static Singleton01 getInstance() {
        return singleton;
    }

}    

如果一个类中的成员属性比较少,且占用的内存资源不多,可以使用饿汉式
如果类中成员都是比较重的资源,那这种方式就会有些不妥

2. 懒汉式

/**
 * 懒汉式
 * 虽然达到了按需初始化的目的,但是带来了多线程访问不安全的问题
 * 当多个线程同时进到if判断里,会多次被创建
 */
public class Singleton02 {

    private static Singleton02 singleton;

    private Singleton02() {
    }

    public static Singleton02 getInstance() {
        if (singleton == null) {
            singleton = new Singleton02();
        }
        return singleton;
    }
}

3. 懒汉式增强(Double-Check)

/**
 * 采用懒汉式+数据同步的方式
 * 满足了懒加载与实例的唯一性
 * 但是synchronized排他性导致性能低下
 */
public class Singleton04 {
    //考虑为什么要加volatile?美团面试题,DCL单例是否有必要加volatile?
    private static volatile Singleton04 singleton;

    private Socket socket;	

    private Singleton04() {
	//进行socket实例化
    }

    public static Singleton04 getInstance() {
      if (singleton == null) {
          synchronized (Singleton04.class) {
              if (singleton == null) {
                  singleton = new Singleton04();
              }
          }
      }
      return singleton;
    }
 } 

4. 静态内部类

/**
 * 静态内部类
 * jvm保证单例
 * 加载外部类不会加载内部类,这样可以实现懒加载
 */
public class Singleton05 {


    private Singleton05() {
    }

    private static class Singleton05Holder {
        private static final Singleton05 singleton = new Singleton05();
    }

    public static Singleton05 getInstance() {
        return Singleton05Holder.singleton;
    }


    /**
     * 测试代码
     *
     * @param args
     */
    public static void main(String[] args) {
        for (int i = 0; i < 10; i++) {
            new Thread(() -> {
                Singleton05 singleton02 = Singleton05.getInstance();
                System.out.println(singleton02.hashCode());
            }).start();
        }
    }
}

在Singleton05类中并没有该类的实例的静态成员,而是放到静态内部类Holder中,因此Singleton05类的初始化并不会创建该类的实例,只有当Holder被主动引用的时候才会创建Singleton05类的实例,Singleton05实例的创建过程在Java程序编译时期收集至()方法中,该方法是同步方法,可以保证内存的可见性、JVM指令的顺序性和原子性,所以该方式的单例设计是最好的设计之一,也是目前使用比较广泛的设计之一

5. 完美方式

/**
 * effective java 给出的完美方式
 * 不仅解决线程同步,还可以防止反序列化
 */
public enum Singleton06 {

    INSTANCE;

    /**
     * 测试代码
     *
     * @param args
     */
    public static void main(String[] args) {
        for (int i = 0; i < 10; i++) {
            new Thread(() -> {
                Singleton06 singleton02 = Singleton06.INSTANCE;
                System.out.println(singleton02.hashCode());
            }).start();
        }


    }
}
分享到:
Graphpad Prism 破解 mac win
@Resource与@AutoWired 区别
  • 文章目录
  • 站点概览
柴子

内蒙 柴子

what do U want?

Github QQ Email RSS
最喜欢的电影
最喜欢的游戏
最喜欢的音乐
最喜欢的图书
最喜欢的动漫
夏洛特的烦恼
英雄联盟
痴心绝对
数据库从入门到删库跑路
斗破苍穹
看爆 Top5
  • 微信getUserProfile兼容性调整以及uniapp写法 2,040次看爆
  • gateway转发微服务请求丢失header参数 1,016次看爆
  • mybatis-plus代码生成器 950次看爆
  • SpringBoot防重复提交与限流的优雅解决 546次看爆
  • Spring Boot Security从入门到进阶到高级 544次看爆
转载注明出处

站点已萌萌哒运行 00 天 00 小时 00 分 00 秒(●'◡'●)ノ♥

Copyright © 2022 柴子 京ICP备17035556号-1

由 Halo 强力驱动 · Theme by Sagiri · 站点地图