zoukankan      html  css  js  c++  java
  • java设计优化--单例模式

    单例模式是一种对象创建模式,确保系统中一个类只有一个实例。

    在java语言中,这样做有两大好处:

    1.对于频繁使用的对象,可以省略创建对象所话费的时间;

    2.由于new操作的次数减少,对于系统内存的使用频率降低,这样减少GC的压力,缩短GC停顿的时间。

    单例模式细分:

    1.

     1 public class Singleton{
     2     private Singleton(){
     3         System.out.println("Singleton.Singleton()");
     4     }
     5     
     6     private static Singleton singleton = new Singleton();
     7     
     8     public static Singleton getInstance(){
     9         return singleton;
    10     }
    11 }

    注意:首先单例类必须有一个private访问级别的构造函数,确保单例不会被系统其他代码实例化;其次,singleton成员变量和getInstance()方法必须是static的。

    这个单例类创建十分简单,而且非常可靠。唯一的缺点是无法对singleton做延迟加载,例如由于单例创建过程很慢,由于成员变量定义为static,在jvm加载单例类时,单例对象也会被创建,那么在任何用到单例类的地方都会创建单例对象,不管单例对象是否被用到。例如:

    public class Singleton{
        private Singleton(){
            System.out.println("Singleton.Singleton()");
        }
        
        private static Singleton singleton = new Singleton();
        
        public static Singleton getInstance(){
            return singleton;
        }
        
        public static void createString(){
            System.out.println("Singleton.createString()");
        }
    }

    2.为了提高相关函数的调用速度,就需要引入懒加载机制。

     1 package com.luchao.singtonle;
     2 
     3 public class LazySingleton {
     4     private LazySingleton() {
     5         System.out.println("LazySingleton.LazySingleton()");
     6     }
     7     private static LazySingleton lazyInstance = null;
     8     
     9     public synchronized static LazySingleton getInstance(){
    10         if(lazyInstance==null)
    11             lazyInstance = new LazySingleton();
    12         return lazyInstance;
    13     }
    14 }

    对于静态变量singleton初始化赋值为null,确保系统启动时没有额外的负荷。在getInstance()方法中,判断当前实例十分已经存在,如果存在则返回,如果不存在,再建单例。getInstance()必须为同步方法,因为在多线程环境下,当线程1正在建单例,未完成赋值前,线程2可能判断instance为null,故线程2将启动建立新建单例的程序,导致多个单例被创建。

    上面实例单例实现,虽然实现了延迟加载,但是引入了同步方法,在多线程环境下,耗时远大于第一个单例程序。

    3.单例模式使用内部类来维护单例的创建

     1 public class StaticSingleton {
     2     private StaticSingleton() {
     3         System.out.println("StaticSingleton.StaticSingleton()");
     4     }
     5     
     6     private static class SingletonHolder{
     7         private static StaticSingleton ataticSingleton = new         StaticSingleton();
     8     } 
     9     
    10     public static StaticSingleton getInstance(){
    11         return SingletonHolder.ataticSingleton;
    12     }
    13     
    14 }

    StaticSingleton被加载时,内部类不会被实例化,确保StaticSingleton类被载入jvm时,不会被初始化单例类,而当getInstance()方法被调用时,才加载SingletonHolder,从而初始化instance。同时用于实例的建立在类加载时完成,故天生对线程友好。

    使用内部类完成单利模式,既可以做到延迟加载,也不用使用同步关键字,是一种比较完善的做法。

  • 相关阅读:
    通过HttpListener实现简单的Http服务
    WCF心跳判断服务端及客户端是否掉线并实现重连接
    NHibernate初学六之关联多对多关系
    NHibernate初学五之关联一对多关系
    EXTJS 4.2 资料 跨域的问题
    EXTJS 4.2 资料 控件之Grid 那些事
    EXTJS 3.0 资料 控件之 GridPanel属性与方法大全
    EXTJS 3.0 资料 控件之 Toolbar 两行的用法
    EXTJS 3.0 资料 控件之 combo 用法
    EXTJS 4.2 资料 控件之 Store 用法
  • 原文地址:https://www.cnblogs.com/lcngu/p/4968444.html
Copyright © 2011-2022 走看看