zoukankan      html  css  js  c++  java
  • java单例支持高并发

    单例对象(Singleton)是一种常用的设计模式。在Java应用中,单例对象能保证在一个JVM中,该对象只有一个实例存在。这样的模式有几个好处:
    
    1、某些类创建比较频繁,对于一些大型的对象,这是一笔很大的系统开销。
    
    2、省去了new操作符,降低了系统内存的使用频率,减轻GC压力。
    
    3、有些类如交易所的核心交易引擎,控制着交易流程,如果该类可以创建多个的话,系统完全乱了。(比如一个军队出现了多个司令员同时指挥,肯定会乱成一团),所以只有使用单例模式,才能保证核心交易服务器独立控制整个流程。
    
    首先我们写一个简单的单例类:

    public class Singleton {
    
        /* 持有私有静态实例,防止被引用,此处赋值为null,目的是实现延迟加载 */
        private static Singleton instance = null;
    
        /* 私有构造方法,防止被实例化 */
        private Singleton() {
        }
    
        /* 静态工程方法,创建实例 */
        public static Singleton getInstance() {
            if (instance == null) {
                instance = new Singleton();
            }
    这个类可以满足基本要求,但是,像这样毫无线程安全保护的类,如果我们把它放入多线程的环境下,肯定就会出现问题了,如何解决?我们首先会想到对getInstance方法加synchronized关键字,如下:
    public static synchronized Singleton getInstance() {
            if (instance == null) {
                instance = new Singleton();
            }
            return instance;
        }
    但是,synchronized关键字锁住的是这个对象,这样的用法,在性能上会有所下降,因为每次调用getInstance(),都要对对象上锁,事实上,只有在第一次创建对象的时候需要加锁,之后就不需要了,所以,这个地方需要改进。我们改成下面这个:
    public class Singleton {
    
        /* 私有构造方法,防止被实例化 */
        private Singleton() {
        }
    
        /* 此处使用一个内部类来维护单例 */
        private static class SingletonFactory {
            private static Singleton instance = new Singleton();
        }
    
        /* 获取实例 */
        public static Singleton getInstance() {
            return SingletonFactory.instance;
        }
    
        /* 如果该对象被用于序列化,可以保证对象在序列化前后保持一致 */
        public Object readResolve() {
            return getInstance();
        }
    }
    上述单例模式使用内部类来维护单例的实现,JVM内部的机制能够保证当一个类被加载的时候,这个类的加载过程是线程互斥的。这样当我们第一次调用getInstance的时候,JVM能够帮我们保证instance只被创建一次,并且会保证把赋值给instance的内存初始化完毕,这样我们就不用担心上面的问题。同时该方法也只会在第一次调用的时候使用互斥机制,这样就解决了低性能问题。这样我们暂时总结一个完美的单例模式:
    其实说它完美,也不一定,如果在构造函数中抛出异常,实例将永远得不到创建,也会出错。所以说,十分完美的东西是没有的,我们只能根据实际情况,选择最适合自己应用场景的实现方法。也有人这样实现:因为我们只需要在创建类的时候进行同步,所以只要将创建和getInstance()分开,单独为创建加synchronized关键字,也是可以的:
    public class SingletonTest {
    
        private static SingletonTest instance = null;
    
        private SingletonTest() {
        }
    
        private static synchronized void syncInit() {
            if (instance == null) {
                instance = new SingletonTest();
            }
        }
    
        public static SingletonTest getInstance() {
            if (instance == null) {
                syncInit();
            }
            return instance;
        }
    }
    

      参考文档:http://m.blog.csdn.net/article/details?id=52445402





  • 相关阅读:
    变量的创建和初始化
    HDU 1114 Piggy-Bank (dp)
    HDU 1421 搬寝室 (dp)
    HDU 2059 龟兔赛跑 (dp)
    HDU 2571 命运 (dp)
    HDU 1574 RP问题 (dp)
    HDU 2577 How to Type (字符串处理)
    HDU 1422 重温世界杯 (dp)
    HDU 2191 珍惜现在,感恩生活 (dp)
    HH实习 acm算法部 1689
  • 原文地址:https://www.cnblogs.com/yinliang/p/6421001.html
Copyright © 2011-2022 走看看