zoukankan      html  css  js  c++  java
  • Java设计模式偷跑系列(六)Singleton模式的建模与实现

    转载请注明出处:http://blog.csdn.net/lhy_ycu/article/details/39784403


    单例模式(Singleton):是一种经常使用的设计模式。

    在Java应用中。单例对象能保证在一个JVM中。该对象仅仅有一个实例存在。

    优点主要有:1、某些类创建比較频繁,对于一些大型的对象,这是一笔非常大的系统开销。

    2、省去了new操作符,减少了系统内存的使用频率,减轻GC压力。


    单例模式主要有两种实现方式:1、懒汉式。2、饿汉式


    一、uml建模


    二、代码实现:

     1、懒汉式

    /**
     * 演示样例:单例--单例对象能保证在一个JVM中。该对象仅仅有一个实例存在。
     * 
     * 缺点:这样的做法在多线程环境下,不安全
     * 
     * 懒汉式
     */
    
    class Singleton {
    	/**
    	 * 持有私有静态变量(也称类变量),防止被引用
    	 * 
    	 * 此处赋值为null。目的是实现延迟载入 (由于有些类比較庞大,所以延迟载入有助于提升性能)
    	 */
    	private static Singleton instance = null;
    
    	/** 私有构造方法,防止被实例化 */
    	private Singleton() {
    
    	}
    
    	/** 静态工厂方法,创建实例 --仅仅只是这里是创建自己,并且仅仅能创建一个 */
    	public static Singleton getInstance() {
    		if (instance == null) {
    			instance = new Singleton();
    		}
    		return instance;
    	}
    
    	public void info() {
    		System.out.println("this is a test method...");
    	}
    }
    
    /**
     * client測试类
     * 
     * @author Leo
     */
    public class Test {
    	public static void main(String[] args) {
    		Singleton s1 = Singleton.getInstance();
    		/**
    		 * 调用普通方法
    		 */
    		s1.info();
    		Singleton s2 = Singleton.getInstance();
    		/**
    		 * 执行结果为true。说明s1、s2这两个类变量都指向内存中的同一个对象
    		 */
    		System.out.println(s1 == s2);
    	}
    }


    2、饿汉式

    /**
     * 饿汉式
     */
    
    class Singleton {
    	private static Singleton instance = new Singleton();
    
    	private Singleton() {
    
    	}
    
    	public static Singleton getInstance() {
    		return instance;
    	}
    
    	public void info() {
    		System.out.println("this is a test method...");
    	}
    }
    
    /**
     * client測试类
     * 
     * @author Leo
     */
    public class Test {
    	public static void main(String[] args) {
    		Singleton s1 = Singleton.getInstance();
    		/**
    		 * 调用普通方法
    		 */
    		s1.info();
    		Singleton s2 = Singleton.getInstance();
    		/**
    		 * 执行结果为true,说明s1、s2这两个类变量都指向内存中的同一个对象
    		 */
    		System.out.println(s1 == s2);
    	}
    
    }

    3、假设考虑多线程,那么getInstance()方法要加同步synchronized,这时饿汉式比懒汉式要好。虽然资源利用率要差,可是不用同步。

    /**
     * 
     * 考虑多线程的时候。以下这样的做法能够參考一下:--懒汉式
     * 
     * 在创建类的时候进行同步。所以仅仅要将创建和getInstance()分开,单独为创建加synchronizedkeyword
     * 
     * 这样的做法考虑性能的话,整个程序仅仅需创建一次实例,所以性能也不会有什么影响。
     * 
     * @author Leo
     */
    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;
    	}
    }

    三、总结

    单例模式保证了一个类仅仅有一个实例,且提供一个訪问全局点的方式,更加灵活的保证了实例的创建和訪问约束。

    系统中仅仅有一个实例。因此构造方法应该为私有 饿汉式:类载入时直接创建静态实例。懒汉式:第一次须要时才创建一个实例,那么getInstance方法要加同步 饿汉式比懒汉式要好。虽然资源利用率要差。可是不用同步。



    版权声明:本文博客原创文章,博客,未经同意,不得转载。

  • 相关阅读:
    一次sqlldr性能测试案例
    Java过滤特殊字符的正则表达式
    朝阳自行成交过户流程
    direct=true 错误处理方法 (关于 Oracle 的数据导入导出及 Sql Loader (sqlldr) 的用法
    SQLLDR直接加载几个参数的测试
    处理超出打开游标的最大数异常(ORA01000: maximum open cursors exceeded)
    java 用PreparedStatement来setDate,用问号的形式给日期问号赋值
    linux下的文件结构介绍
    用SQLLDR来装载CLOB/BLOB列的控制文件例子
    关于oracle日期的说明
  • 原文地址:https://www.cnblogs.com/mengfanrong/p/4734720.html
Copyright © 2011-2022 走看看