设计模式记录(2.2)
第十五章 单例模式
单例模式的要点
显然单例模式的要点有三个:一个某个类只能有一个实例;二是它必须自行创建这个事例;三是它必须自行向整个系统提供这个事例。
单例模式的结构
单例类只能有一个实例。
单例类必须自己创建自己的唯一的实例。
单例类必须给所有其他对象提供这一实例。
由于java语言的特点,使得单例模式在java语言的实现上有自己的特点。这些特点主要表现在单例类如何将自己实例化上。
饿汉式单例类
饿汉式单例类是在java语言里实现起来最为简便的单例类,实现代码如下:
package com.javapatterns.singleton.demos;public class EagerSingleton { private static final EagerSingleton m_instance = new EagerSingleton(); private EagerSingleton() { } public static EagerSingleton getInstance() { return m_instance; } }
package com.javapatterns.singleton.demos;public class LazySingleton{ private static LazySingleton m_instance = null; private LazySingleton() { } synchronized public static LazySingleton getInstance() { if (m_instance == null) { m_instance = new LazySingleton(); } return m_instance;} }
package com.javapatterns.singleton.demos;import java.util.HashMap;public class RegSingleton { protected RegSingleton() {} static public RegSingleton getInstance(String name) { if (name == null) { name = "com.javapatterns.singleton.demos.RegSingleton"; } System.out.println("From RegSingleton: requesting for " + name ); if (m_registry.get(name) == null) { try { m_registry.put( name, Class.forName(name).newInstance() ) ; } catch(ClassNotFoundException e) { System.out.println("Class " + name + " is not found."); } catch(InstantiationException e) { System.out.println("Class " + name + " can not be instantiated."); } catch(IllegalAccessException e) { System.out.println("Class " + name + " can not be accessed."); } } return (RegSingleton) (m_registry.get(name) ); } static private HashMap m_registry = new HashMap(); static { RegSingleton x = new RegSingleton(); m_registry.put( x.getClass().getName() , x); } public String about() { return "Hello, I am RegSingleton."; }}
package com.javapatterns.singleton.demos;import java.util.HashMap;public class RegSingletonChild extends RegSingleton{ public RegSingletonChild() {} static public RegSingletonChild getInstance() { return (RegSingletonChild) RegSingleton.getInstance( "com.javapatterns.singleton.demos.RegSingletonChild" ); } public String about() { return "Hello, I am RegSingletonChild."; }}
package com.javapatterns.singleton.demos;public class RegSingletonTest{ public static void main(String[] args) { System.out.println( RegSingleton.getInstance("com.javapatterns.singleton.demos.RegSingleton").about() ) ; System.out.println( RegSingleton.getInstance(null).about() ) ; System.out.println( RegSingleton.getInstance("com.javapatterns.singleton.demos.RegSingletonChild").about() ) ; System.out.println( RegSingletonChild.getInstance().about()) ; }}
From RegSingleton: requesting for com.javapatterns.singleton.demos.RegSingletonHello, I am RegSingleton.From RegSingleton: requesting for com.javapatterns.singleton.demos.RegSingletonHello, I am RegSingleton.From RegSingleton: requesting for com.javapatterns.singleton.demos.RegSingletonChildHello, I am RegSingletonChild.From RegSingleton: requesting for com.javapatterns.singleton.demos.RegSingletonChildHello, I am RegSingletonChild.
import java.io.*;public class CmdTest {public static void main(String[] args) {Process proc = Runtime.getRuntime().exec("notepad.exe");}}
package com.javapatterns.singleton.demos;public class LazySingleton{ public LazySingleton() { } synchronized public static LazySingleton getInstance() { if (m_instance == null) { m_instance = new LazySingleton(); } return m_instance;} private static LazySingleton m_instance = null;}
class Foo {private Helper helper = null;public synchronized Helper getHelper() {if(helper == null) {helper = new Heper();return helper;}}}
class Foo {private Helper helper = null;public Helper getHelper() {if(helper == null) { //第一次检查//这里会有多于一个的线程同时到达synchronized (this) {//这里在每个时刻只能有一个线程if(helper == null) { //第二次检查helper = new Helper();}}}return helper;}}
package com.javapatterns.multilingual.dice;import java.util.Random;import java.util.Date;public class Die{ private static Die die1 = new Die(); private static Die die2 = new Die(); private Die() { } public static Die getInstance(int whichOne) { if (whichOne == 1) { return die1; } else { return die2; } } public synchronized int dice() {Date d = new Date();Random r = new Random( d.getTime() );int value = r.nextInt();value = Math.abs(value);value = value % 6;value += 1;System.out.println(value); return value; }}
package com.javapatterns.multilingual.dice;public class Client{ private static Die die1;private static Die die2; public static void main(String[] args) {die1 = Die.getInstance(1); die2 = Die.getInstance(2); die1.dice(); die2.dice(); }}