95 单例

作者: 滔滔逐浪 | 来源:发表于2021-07-19 20:20 被阅读0次

1,懒汉式线程不安全


package com.taotao.rfspringboot.day14;

import lombok.Synchronized;

import java.util.concurrent.SynchronousQueue;

/**
*@title: Singleton01
*@description; 
*@author wangj
*@date 2021/7/19 20:23
*/  

public class Singleton01 {
    //懒汉式,当真正需要创建对象的时候才会创建对象
    private  Singleton01 singleton01;

    //单例的特点,在我们的jvm里只能存在一个单例
    //2无参构造函数私有化
    private Singleton01(){

    }


    //根据该方法使用到哪里对象
    public    Singleton01  getSingleton01() {
        if(singleton01==null){
            singleton01=new Singleton01();
        }
        return singleton01;
    }
}

懒汉式 第一次new出该对象已经赋值singleton 后面所有的线程直接获取singleton 对象不需要重复new
2,懒汉式线程安全;
3,懒汉式双重检验锁
能够保证线程的安全,只会创建单例对象的时候上锁,获取该单例对象不会上锁,效率比较高,注意 volatile 关键字避免重排序

 //根据该方法使用到哪里对象
    public  static     Singleton01  getSingleton01() {
        if(singleton01==null){
            synchronized(Singleton01.class){
                singleton01=new Singleton01();
            }

        }
        return singleton01;
    }

懒汉式 懒加载 当我们需要对象时,才会创建对象,节约该内心
4,饿汉式,提前创建对象,优点 先天性保证安全,比较占内存。


package com.taotao.rfspringboot.day14;

/**
*@title: Singleton02
*@description;  饿汉式
*@author wangj
*@date 2021/7/19 21:42
*/  

public class Singleton02 {
    /**
     * 饿汉式 当我们的class文件没加载 --类加载器提前创建对象
     *缺陷: 如果没有使用对象的时候创建对象 占用内存
     * 优点,先天性线程安全
     */
    private  static    Singleton02 singleton=new Singleton02();

    /**
     * 饿汉式
     */
    private  Singleton02()
    {

    }

    public  Singleton02 getSingleton() {
        return singleton;
    }

    public static void main(String[] args) {
        Singleton02 singleton021=Singleton02.singleton;
        Singleton02 singleton02=Singleton02.singleton;
        System.out.println(singleton02==singleton021);
    }
}

5,静态代码块



package com.taotao.rfspringboot.day14;

/**
 * @author wangj
 * @title: Singleton03
 * @description;
 * @date 2021/7/19 21:53
 */

public class Singleton03 {

    private static Singleton03 singleton = null;

    /**
     * 静态代码块初始化静态对象
     * 只会执行一次
     */
    static {
        singleton = new Singleton03();
    }

    public static Singleton03 getSingleton() {
        return singleton;
    }

    public static void main(String[] args) {
        Singleton03 singleton01=Singleton03.getSingleton();
        Singleton03 singleton02=Singleton03.getSingleton();
        System.out.println(singleton01==singleton02);

    }
}

6,静态内部类


package com.taotao.rfspringboot.day14;

/**
 * @author wangj
 * @title: Singleton06
 * @description;
 * @date 2021/7/20 7:04
 */

public class Singleton06 {
    private Singleton06() {
        System.out.println("单例对象初始化");
    }

    private static Singleton06 singleton;

    /**
     * 静态内部类
     */
    public static class Singletonolder {
        private static Singleton06 singleton06 = new Singleton06();

    }

    public static Singleton06 getSingleton() {
        return Singletonolder.singleton06;
    }

    public static void main(String[] args) {
        Singleton06 singleton01 = Singleton06.getSingleton();
        Singleton06 singleton02 = Singleton06.getSingleton();
        System.out.println(singleton01==singleton02);

    }
}

7,枚举实现单例; 枚举属于最安全的单例,不能被反射 序列化保证单例。

创建对象的方式:
1,直接new对象
2,采取克隆对象
3,使用反射创建对象
4序列化与反序列化

如何破解单例模式?
1,反射的机制破解单例


package com.taotao.rfspringboot.day14;

import lombok.Synchronized;

import java.util.concurrent.SynchronousQueue;

/**
*@title: Singleton01
*@description; 
*@author wangj
*@date 2021/7/19 20:23
*/  

public class Singleton01 {
    //懒汉式,当真正需要创建对象的时候才会创建对象
    private  static Singleton01 singleton01;

    //单例的特点,在我们的jvm里只能存在一个单例
    //2无参构造函数私有化
    private Singleton01() throws Exception {
        System.out.println("无参构造函数");
            if(singleton01!=null){
                throw new Exception("该对象已经创建");
            }
    }


    //根据该方法使用到哪里对象
    public  static     Singleton01  getSingleton01() throws Exception {
        if(singleton01==null){
            synchronized(Singleton01.class){
                //双重检验锁
                //第一个判断 只有在new 单例对象的时候才会释放锁
                //第二个判断 如果之前获取的线程new成功后无需创建
                if(singleton01==null){
                    singleton01=new Singleton01();
                }

            }

        }
        return singleton01;
    }

    public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException {
        //破解单例,当前对象可以new
        //使用反射技术

        Class<?> aClass=Class.forName("com.taotao.rfspringboot.day14.Singleton01");

        //调用无参构造函数初始化
        Singleton01 singleton01= (Singleton01) aClass.newInstance();
        Singleton01 singleton02= (Singleton01) aClass.newInstance();
        System.out.println(singleton01==singleton02);
    }
}


2序列化破解单例:
序列化概念: 将对象转换成二进制的形式直接存放在本地 将该对象持久化到硬盘中-json 将对象转换成json --序列化
反序列化概念: 从硬盘中读取二进制变为对象 json 将该json转换成对象--反序列化。

相关文章

  • 95 单例

    1,懒汉式线程不安全 懒汉式 第一次new出该对象已经赋值singleton 后面所有的线程直接获取singlet...

  • 大牧絮叨设计模式:单例模式

    [TOC] 1、单例模式概述 单例模式(Singleton)[GOF95]是一种对象的创建模式,确保系统中使用了单...

  • Effective Java 3rd 条目3 用私有构造子或者枚

    单例(singleton)仅仅是一个恰好能实例化一次的类[Gamma95]。单例一般代表一个无状态的对象(比如,一...

  • 急了急了,破防单例模式

    本文主要介绍单例创建的集中方式和反射给单例造成的影响。 [#%E5%8D%95%E4%BE%8B%E7%9A%84...

  • Spring的scope="prototype"属性

    spring 默认scope 是单例模式[https://www.baidu.com/s?wd=%E5%8D%95...

  • Android设计模式总结

    单例模式:饿汉单例模式://饿汉单例模式 懒汉单例模式: Double CheckLock(DCL)实现单例 Bu...

  • IOS单例模式的底层原理

    单例介绍 本文源码下载地址 1.什么是单例 说到单例首先要提到单例模式,因为单例模式是单例存在的目的 单例模式是一...

  • 【设计模式】单例模式

    单例模式 常用单例模式: 懒汉单例模式: 静态内部类单例模式: Android Application 中使用单例模式:

  • 2020-11-02-Spring单例 vs. 单例模式

    Spring 单例不是 Java 单例。本文讨论 Spring 的单例与单例模式的区别。 前言 单例是 Sprin...

  • IOS学习笔记之单例

    单例介绍 1.什么是单例 说到单例首先要提到单例模式,因为单例模式是单例存在的目的 单例模式是一种常用的软件设计模...

网友评论

      本文标题:95 单例

      本文链接:https://www.haomeiwen.com/subject/teghmltx.html