闲来无事看之前的博客,发现单例模式只会写2中。所以再重新开一篇博客,将目前自己所能理解的几种单例模式全部总结下。 ___________________________________________________________________________________________________________ 1、懒汉式(最基本的) 单线程版 写单例模式(饿汉式)的步骤: 1):必须在该类中,自己先创建出一个对象。 2):私有化自身的构造器,防止外界通过构造器创建新的对象。 3):想外暴露一个公共的静态方法用于获取自身的对象 缺点:单线程是没问题的 但是多线程就会产生线程问题 下面会介绍多线程版本 多线程版本线程不安全(最简单的案例): 2、饿汉式(最基本的) 优点:线程天生安全 类在整个生命周期中只会被加载一次,因此该单例类只会创建一个实例,也就是说,线程每次都只能也必定只可以拿到这个唯一的对象 3、枚举 有兴趣可以测试下 ,我这比较简单 4、静态内部类 5、DCL(双重检验锁) 在 new MultiSingletonDCL();时候由于会发生指令重排序 可能会出现问题 因此加上关键字 volatile 本文如有问题,希望大佬指正。不胜感激。
// 懒汉式类初始化的,不会创建该对象,真正需要的时候才会加载(创建),天生线程不安全,需要解决线程安全问题,所有效率比较低 public class SingletonLazy { private SingletonLazy() { System.out.println(Thread.currentThread().getName()); } private static SingletonLazy singletonLazy; public static SingletonLazy getInstance() { if (singletonLazy == null) { singletonLazy = new SingletonLazy(); } return singletonLazy; } public static void main(String[] args) { SingletonLazy singletonLazy1 = SingletonLazy.getInstance(); SingletonLazy singletonLazy2 = SingletonLazy.getInstance(); System.out.println(singletonLazy1 == singletonLazy2); // true } }
public class SingletonLazy { private SingletonLazy() { System.out.println(Thread.currentThread().getName()); } private static SingletonLazy singletonLazy; public static SingletonLazy getInstance() { if (singletonLazy == null) { singletonLazy = new SingletonLazy(); } return singletonLazy; } public static void main(String[] args) { for (int i = 0; i <= 500; i++) { new Thread(() -> { try { getInstance(); Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } }, String.valueOf(i)).start(); } } }
缺点:类加载的时候就会加载 static 对象 如果暂时用不到呢 就会占用极大的内存
public class SingletonHungry { // 会浪费内存 // byte[] data1 = new byte[1024*1024]; // byte[] data2 = new byte[1024*1024]; private SingletonHungry() { System.out.println(Thread.currentThread().getName()); } //小知识: 当使用static 修饰时 会存档在 JVM的方法区 JVM垃圾回收机制 不会进行回收 private static final SingletonHungry singletonDemo = new SingletonHungry(); private static SingletonHungry getInstance() { return singletonDemo; } public static void main(String[] args) { SingletonHungry singletonDemo = getInstance(); SingletonHungry singletonDemo2 = getInstance(); System.out.println(singletonDemo == singletonDemo2); // true } }
枚举是一个特殊的类
内部将构造器进行私有化,因此不能通过New 的方式进行创建
public enum EnumSingleton { INSTANCE; public EnumSingleton getInstance(){ return INSTANCE; } }
public class SingletonStatic { private SingletonStatic() {} public static class SingletonClassInstance{ private static final SingletonStatic single = new SingletonStatic(); } public static SingletonStatic getInstance(){ return SingletonClassInstance.single; } public static void main(String[] args) { SingletonStatic singleton1 = SingletonStatic.getInstance(); SingletonStatic singleton2 = SingletonStatic.getInstance(); System.out.println(singleton1 ==singleton2); } }
// 1. 分配内存空间 // 2. 执行构造方法,初始化对象 // 3. 把这个对象指向这个空间
// 双锁机制的出现是为了解决前面同步问题和性能问题 public class SingletonDCL { private volatile static MultiSingletonDCL multiSingletonDCL; private SingletonDCL() { System.out.println(Thread.currentThread().getName()); } private static SingletonDCL getInstance() { if (singletonLazyDCL == null){ synchronized (SingletonDCL.class){ if (singletonLazyDCL == null){ singletonLazyDCL = new SingletonDCL(); } } } return singletonLazyDCL; } public static void main(String[] args) { SingletonDCL instance = SingletonDCL.getInstance(); SingletonDCL instance2 = SingletonDCL.getInstance(); System.out.println(instance == instance2); } }
本网页所有视频内容由 imoviebox边看边下-网页视频下载, iurlBox网页地址收藏管理器 下载并得到。
ImovieBox网页视频下载器 下载地址: ImovieBox网页视频下载器-最新版本下载
本文章由: imapbox邮箱云存储,邮箱网盘,ImageBox 图片批量下载器,网页图片批量下载专家,网页图片批量下载器,获取到文章图片,imoviebox网页视频批量下载器,下载视频内容,为您提供.
阅读和此文章类似的: 全球云计算