• java设计模式1--单例模式


    单例模式介绍

    所谓单例模式,就是采取一定的方法保证在整个的软件系统中,只能存在一个对象实例,并且该实例只提供一个取得其对象实例的方法(静态方法)

    单例模式有八种方法

    1、饿汉式(静态常量)

    2、饿汉式(静态代码块)

    3、懒汉式(线程不安全)

    4、懒汉式(线程安全,同步方法)

    5、懒汉式(线程安全,同步代码块)

    6、双重检查

    7、静态内部类

    8、枚举

     

    饿汉式(静态常量)

    思路

    1、构造器私有化(防止new)

    2、类的内部创建对象

    3、向外暴露一个静态的公共方法.getInstance

    代码

    class Singleton {
        private Singleton() {
        }
    
        private final static Singleton instance = new Singleton();
    
        public static Singleton getInstance() {
            return instance;
        }
    }

    优缺点

    1、优点:这种写法比较简单,就是在类装在的时候就完成实例化.避免线程同步问题.

    2、缺点:在类装载的时候,就已经创建对象,若不需要用到可能会造成内存浪费.

    3、结论:可用,但是可能造成内存浪费

     

    饿汉式(静态代码块)

    class Singleton {
        private final static Singleton instance;
    
        private Singleton() {
        }
    
    
        static {
            instance = new Singleton();
        }
    
        public static Singleton getInstance() {
            return instance;
        }
    }

    和上面一样,也是类加载的时候创建对象,不能确保是否还有其他静态方式创建对象,如果用不到时,可能造成内存浪费.

     

    懒汉式(线程不安全)

    class Singleton {
        private static Singleton instance;
    
        private Singleton() {
    
        }
    
        public static Singleton getInstance() {
            if (instance == null) {
                return new Singleton();
            }
            return instance;
        }
    }

    1、起到了lazy loading的效果,但是只能在单线程下使用

    2、线程不安全

    3、在实际开发中不可用

     

    懒汉式线程安全

    class Singleton{
        private static Singleton instance;
    
        private Singleton(){
    
        }
    
        public static synchronized Singleton getInstance(){
            if (instance == null){
                return new Singleton();
            }
            return instance;
        }
    }

    1、线程安全

    2、效率低

     

    懒汉式(不可用,线程不安全)

    class Singleton {
        private static Singleton instance;
    
        private Singleton() {
        }
    
        public Singleton getInstance(){
            if (instance == null){
                synchronized (Singleton.class){
                    return new Singleton();
                }
            }
            return instance;
        }
    }

    1、线程不安全

    2、效率低

     

    双重检查判断

    class Singleton {
        private static Singleton instance;
    
        private Singleton() {
        }
    
        public Singleton getInstance() {
            if (instance == null) {
                synchronized (Singleton.class) {
                    if (instance == null) {
                        return new Singleton();
                    }
                }
            }
            return instance;
        }
    }

    1、线程安全

    2、效率较高,推荐使用

     

    静态内部类

    class Singleton {
        private static volatile Singleton instance;
    
        private Singleton() {
        }
    
        private static class SingletonInstance {
            private static final Singleton INSTANCE = new Singleton();
        }
    
        public static Singleton getInstance() {
            return SingletonInstance.INSTANCE;
        }
    }

    1、用类加载的机制保证初始化时只有一个线程(静态内部类只有用到时才加载,且线程安全).

    2、静态内部类方式在Singleton类被装载时并不会立即实例化(静态内部类只有用到时才加载),而是调用时,才完成类加载,也就是调用getInstance

    3、只有当静态内部类被主动调用的时候,JVM才会去初始化这个静态内部类,JVM初始化类是线程安全的。

    4、总结:线程安全,利用静态内部类实现lazy loading效率高,推荐使用

     

    枚举法

    enum Singleton{
        INSTANCE;
    }

    1、借助JDK1.5中添加的枚举来实现单例模式.不仅线程安全,还能防止反序列化重新创建新的对象(不能被反射创建)

    2、极度推荐

     

    单例模式注意事项和细节说明

    1、单例模式保证系统内中该类只存在一个对象,节省了系统资源,对于一些需要频繁销毁的对象,用单例模式可以提高系统性能(创建销毁只需一次)

    2、当想实例化一个单例类的时候,必须记住使用相应的获取对象的方法,而不是使用new

    3、使用场景,需要频繁创建和销毁对象,创建重量级对象(消耗的资源,时间多),但又经常使用的对象、如工具类对象、频繁访问的数据库对象、或文件对象(数据源、session工厂)

     

    经典应用场景

    //JDK中,java.lang.Runtime
    
    public class Runtime {
        private static Runtime currentRuntime = new Runtime();
    
        /**
         * Returns the runtime object associated with the current Java application.
         * Most of the methods of class <code>Runtime</code> are instance
         * methods and must be invoked with respect to the current runtime object.
         *
         * @return  the <code>Runtime</code> object associated with the current
         *          Java application.
         */
        public static Runtime getRuntime() {
            return currentRuntime;
        }
    
        /** Don't let anyone else instantiate this class */
        private Runtime() {}
  • 相关阅读:
    【转】算法的时间复杂度
    FFT 物理意义(转)
    【转】FIR学习1
    【转】DFT DTFT DFS FFT的关系
    【转】TCL中的数组
    【转】setup time和hold time的周期问题(slack)
    【转】TCL语法简介
    【转】亚稳态分析
    ubuntu下Samba服务器搭建
    第一次生成uImage出现的问题解决
  • 原文地址:https://www.cnblogs.com/Adam-Ye/p/13500049.html
Copyright © 2020-2023  润新知