SingletonPattern单例模式

单例模式

1.定义

确保某一个类只有一个实例,并且自行实例化并向整个系统提供这个实例java

饿汉式单例模式数据库

public class Singleton {
    private static final Singleton singleton = new Singleton();

    // 构造器私有化,限制产生多个对象
    private Singleton() {}

    // 对外提供静态方法获取实例对象
    public static Singleton getInstence() {
      	return singleton;
    }
}

2.应用

2.1优势

  • 因为单例模式在内存中只有一个实例,减少了内存开支。特别在一个对象须要频繁的建立销毁时,建立销毁时性能没法优化,此时的优点很是明显
  • 因为单例模式只生成一个实例,减小了系统的性能开销。当一个对象须要产生较多的资源时,如读取配置,产生其它以来对象,能够经过在应用启动时直接产生一个单例对象,而后永久驻留内存的方式解决(JavaEE中采用单例模式时须要注意JVM的垃圾回收机制)
  • 单例模式能够避免对同一资源的多重占用,例如写文件操做

2.2缺点

  • 单例模式通常没有接口,扩展性差
  • 单例模式不利于测试。在并行开发环境中,若单例模式没有完成,不能进行测试

2.3使用场景

  • 生成惟一序列号的环境
  • 在整个项目中须要一个共享访问点或共享数据。如一个Web页面上的计数器,使用单例模式保持计数器的值,并确保是线程安全的
  • 建立一个对象时须要消耗的资源过多,如访问IO和数据库等资源
  • 须要定义大量的静态常量和静态方法(如工具类)的环境

2.4注意事项

在该并发状况下,须要注意单例模式的线程同步问题。单例模式有几种不一样的实现方式,饿汉式单例模式不会产生多实例的状况,如下方式则须要考虑线程同步问题安全

懒汉式单例模式并发

public class Singleton {
    private static final Singleton singleton = null;

    // 构造器私有化,限制产生多个对象
    private Singleton() {}

    // 对外提供静态方法获取实例对象
    public static Singleton getInstence() {
        if (singleton == null) {
          singleton = new Singleton();
        }
      
        return singleton;
    }
}

懒汉式单例模式在低并发状况下尚不会出现问题,若系统压力增大,并发量增长时可能在内存中存在多个实例。如一个线程A执行到singleton = new Singleton();但尚未得到到对象,此时对象初始化未完成,第二个线程B执行到if (singleton == null) {那么线程B判断条件也为true,因而继续执行下去,则A和B各得到一个对象。dom

解决单例模式线程不安全的方法,能够在getInstence方法前或方法内加synchronized关键字来实现,建议采用饿汉式单例模式。工具

3.扩展

有上限的多例模式:产生固定数量对象的模式性能

public class Singleton {
    // 定义最多能产生的实例数量
    private static int maxNumOfInstance = 2;

    // 定义一个列表容纳全部实例
    private static List<Singleton> singletonList = new ArrayList<>();

    // 定义当前对象实例的序号
    private static int countNumOfInstance = 0;

    // 产生全部的对象
    static {
        for (int i = 0; i < maxNumOfInstance; i++) {
            singletonList.add(new Singleton())
        }
    }

    private Singleton() {}

    public static Singleton getInstence() {
      	Random random = new Random();
      	countNumOfInstance = random.nextInt(maxNumOfInstance);

      	return singletonList.get(countNumOfInstance);
    }
}

考虑到线程安全问题可使用Vector来代替。采用有上限的多例模式,能够在设计时决定内存中有多少个实例,方便系统扩展,修正单例可能存在的性能问题,提升系统的响应速度。如读取文件,能够在系统启动时完成初始化工做,在内存中启动固定数量的Reader实例。测试

相关文章
相关标签/搜索