zoukankan      html  css  js  c++  java
  • 单例模式

    设计模式之单例模式

    饿汉式(静态变量)

    class Singleton1{
        //1.构造器私有化
        private Singleton1() {
        }
        private static final  Singleton1 singleton = new Singleton1();
        public static Singleton1 getInstance(){
            return singleton;
        }
    }
    

    优点:安全

    缺点:可能造成内存浪费

    饿汉式(静态代码块)

    class Singleton2{
        //构造器私有化
        private Singleton2() {
        }
        private static Singleton2 singleton2;
        static{
            //在静态代码块中完成初始化
            singleton2 = new Singleton2();
        }
        public static  Singleton2 getInstance(){
            return singleton2;
        }
    }
    

    优缺点和上面一样

    懒汉式(线程不安全)

    /**
     * 懒汉式(线程不安全)
     */
    public class TestSingleton3 {
        public static void main(String[] args) {
            for (int i = 0; i < 1000; i++) {
                new Thread(() ->{
                    System.out.println(Thread.currentThread().getName()+"@@"+Singleton3.getInstance().hashCode());
                },String.valueOf(i)).start();
            }
        }
    }
    class Singleton3{
        //构造器私有
        private Singleton3() {
        }
        private static Singleton3 singleton3;
        public static Singleton3 getInstance(){
            if(singleton3==null)
                singleton3 = new Singleton3();
            return singleton3;
        }
    }
    

    image-20200919201435002

    优点:起到了懒加载的效果,但只能在单线程下使用

    缺点:多线程下线程不安全

    懒汉式(同步方法或同步代码块)

    这里只演示同步方法

    class Singleton4 {
        //构造器私有化
        private Singleton4() {
        }
        private static Singleton4 singleton4;
        public static synchronized Singleton4 getInstance() {
            if (singleton4 == null)
                singleton4 = new Singleton4();
            return singleton4;
        }
    }
    

    优点:多线程下安全

    缺点:效率低下

    DCL

    class Singleton5{
        //构造器私有化
        private Singleton5() {
        }
        //注意要加volatile关键字
        //volatile关键字在这里的作用主要是保证可见性
        private static volatile Singleton5 singleton5;
        public static Singleton5 getInstance(){
            if (singleton5==null){
                synchronized (Singleton5.class){
                    if(singleton5==null)
                        singleton5 = new Singleton5();
                }
            }
            return singleton5;
        }
    }
    

    优点:线程安全,延迟加载,效率较高

    在这里说一下volatile的作用

    volatile的三大作用:保证可见性,不保证原子性,禁止指令重排

    笔者认为volatile在这里的作用主要是保证可见性,当一个线程进入到同步代码块中,它创建完对象后,应立刻对其它线程可见。volatile的

    作用就是当被volatile修饰的变量发生变化时,其结果会立刻强制被刷回到主存中,而其它线程会通过总线嗅探机制和缓存一致性协议得知

    自己缓存中的数据已经失效,会等待缓存行对应的主存地址被更新之后,再去读取对应的主存中的新值。

    当然,这只是笔者认为的,网上的答案也是众说纷坛。笔者的答案只能作为参考,如有不对,请告知于我。

    静态内部类

    class Singleton6{
        //构造器私有化
        private Singleton6() {
        }
        //因为外部类加载的时候不会触发静态内部类的加载
        //并且类的静态属性只会在类第一次被加载的时候初始化,
        //所以在这里,JVM帮助我们保证了现成的安全性,在类进行初始化时,别的线程是无法进入的。
        private static class InnerSingleton{
            public static final Singleton6 INSTANCE = new Singleton6();
        }
        public static Singleton6 getInstance(){
            return InnerSingleton.INSTANCE;
        }
    }
    

    优点:线程安全,延迟加载,效率较高

    枚举

    enum  Singleton7{
        INSTANCE;
        public void method(){
            System.out.println("你好呀!!!");
        }
    }
    

    优点:线程安全,可以防止反序列化重新创建新的对象,推荐使用。

  • 相关阅读:
    linux系统分区表修复
    centos 系统下彻底删除mysql
    mysql数据类型
    mysq 数据库基本管理
    centos 网卡聚合及Cisco交换机链路聚合
    Dell 服务器安装方法介绍
    linux分区之gpt(大于2T的分区)
    windows server 2008 远程桌面连接数修改--无限连接
    C# WinForm控件美化扩展系列之ListBox
    C# 文件 文件夹
  • 原文地址:https://www.cnblogs.com/gttttttt/p/13697519.html
Copyright © 2011-2022 走看看