精华内容
下载资源
问答
  • singleton

    2016-04-04 15:12:06
    singleton
    pulbic class Singleton {
    
        //Static variables are initialized only once when 
        //the Classloader load the class for the first time.
        private static Singleton instance = new Singleton();
    
        private Singleton() {}
    
        public static Singleton getInstance() {
            return instance;
        }
    }

    上面代码就是单例模式最简单的实现方式,这种实现方式适合那些在初始化时就要用到单例的情况,这种方式简单粗暴,如果单例对象初始化非常快,而且占用内存非常小的时候这种方式是比较合适的,可以直接在应用启动时加载并初始化 —— Eager Instantiation

    如果单例初始化的操作耗时比较长而应用对于启动速度又有要求,或者单例的占用内存比较大,再或者单例只是在某个特定场景的情况下才会被使用,而一般情况下是不会使用时,使用Eager Instantiation的单例模式就是不合适的,这时候就需要用到Lazy Instantiation的方式去按需延迟加载单例。如下代码:

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

    Eager InstantiationLazy Instantiation的最大区别就是将单例的初始化操作,延迟到需要的时候才进行,这样做在某些场合中有很大用处。比如某个单例用的次数不是很多,但是这个单例提供的功能又非常复杂,而且加载和初始化要消耗大量的资源,这个时候使用Lazy Instantiation就是非常不错的选择。

    多线程下的单例模式
    上面介绍了一些单例模式的基本应用方法,但是上面所说的那些使用方式都是有一个隐含的前提,那就是他们都是应用在单线程条件下,一旦换成了多线程就有出错的风险。
    如果在多线程的情况下,Eager Instantiation不会出现问题,因为JVM只会加载一次单例类,但是Lazy Instantiation可能就会出现重复创建单例对象的问题。为什么会有这样的问题呢?因为Lazy Instantiation在创建单例时是线程不安全的,多个线程可能会并发调用他的 getInstance 方法导致多个线程可能会创建多份相同的单例出来。
    那有没有办法,使Lazy Instantiation的单利模式也是线程安全的呢?答案肯定是有的,就是使用加同步锁的方式去实现。如下代码:

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

    这种是最常见的解决同步问题的一种方式,使用同步锁 synchronized防止多线程同时进入造成instance被多次实例化。

    有没有更好的实现方式呢?答案是肯定的。 我们可以利用JVM的类加载机制去实现。在很多情况下JVM已经为我们提供了同步控制,比如:在static{}区块中初始化的数据,访问final字段时等等。因为在JVM进行类加载的时候他会保证数据是同步的,我们可以这样实现:采用内部类,在这个内部类里面去创建对象实例。这样的话,只要应用中不使用内部类 JVM 就不会去加载这个单例类,也就不会创建单例对象,从而实现Lazy Instantiation的延迟加载和线程安全。如下代码:
    静态内部类:

    pulbic class Singleton {
        //内部类,在加载该内部类是才会去创建单例对象
        private static class SingletonHolder {
            public static Singleton instance = new new Singleton();
        }
    
        private Singleton() {}
    
        public static Singleton getInstance() {
            return SingletonHolder.instance;
        }
    }

    你真的会写单例模式吗——Java实现
    singleton模式四种线程安全的实现

    Java Singleton and Synchronization

    静态内部类什么时候加载呢?
    加载一个类时,其内部类是否同时被加载?引申出单例模式的另一种实现方式
    静态内部类、静态变量的加载次数-理解静态内部类实现线程安全的单例模式
    When is a static nested class (and static members therein) loaded into memory?
    when static variables are initialized in Java
    How static class variables get initialized

    展开全文
  • Singleton

    千次阅读 2018-08-21 19:10:33
    1. 单例模式的实现方式1: ... public class Singleton1 { ... private static final Singleton1 INSTANCE = new Singleton1();    private Singleton1() { }    public static Singleton1 get...

    1. 单例模式的实现方式1:

    package com.object;

    public class Singleton1 {

        private static final Singleton1 INSTANCE = new Singleton1();
        
        private Singleton1() { }
        
        public static Singleton1 getInstance() {
            return INSTANCE;
        }

    }
    2. 单例模式的实现方式2:

    package com.object;

    public class Singleton2 {

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

    }

    3. 单例模式的实现方式3:

    package com.object;

    public class Singleton3 {

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

    }

    4. 单例模式的实现方式4:

    package com.object;

    public class Singleton4 {
        
        private static class SingletonHolder {
            private static final Singleton4 INSTANCE = new Singleton4();
        }

        private Singleton4() { }
        
        public static Singleton4 getInstance() {
            return SingletonHolder.INSTANCE;
        }

    }
     

    展开全文

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 47,794
精华内容 19,117
热门标签
关键字:

singleton