好记性不如铅笔头

java, 编程, 设计模式

设计模式学习笔记:单例模式

单例模式是一种非常常用的设计模式。下面备份下几种常用的单例模板。

github:

https://github.com/cstriker1407/design_pattern 】

CONTENTS

1)懒汉加载:

懒汉加载有很多实现方式,但很多方式都会有多线程同步问题,下面的这种方式规避了多线程的同步问题,并且实现了懒加载。它的核心方式是在单例类中加入了一个内部静态类。

public class Singleton_lazy 
{
	private static class Singleton_lazy_Holder
	{
		static
		{
			System.out.println("Singleton_lazy_Holder loaded");
		}

		private static Singleton_lazy instance = new Singleton_lazy();
	}

	private Singleton_lazy()
	{
		System.out.println("Singleton_lazy instance alloced");
	}

	public static Singleton_lazy getInstance()
	{
		return Singleton_lazy_Holder.instance;
	}
	public void sayHello()
	{
		System.out.println("Hello");
	}


	public static void donth()
	{}
	static
	{
		System.out.println("Singleton_lazy loaded");
	}
}

2)饿汉加载:

饿汉加载是作者最喜欢使用的一种单例实现方式。

{
	private Singleton_hungry(){}
	private static Singleton_hungry instance = new Singleton_hungry();
	public static Singleton_hungry getInstance()
	{
		return instance;
	}
	public void sayHello()
	{
		System.out.println("Hello From" + this.getClass().getName());
	}
}

3)使用枚举来实现一个单例:

作者在搜集单例的资料时发现了这种实现方式,但是并没有具体的在项目中应用。

package design_patterns.singleton;

public enum Singleton_enum
{
    INSTANCE;
    public void sayHello()
    {
    	System.out.println("hello from enum,i=" + i);
    }
    private int i = 0;
}

4)双重检测式 懒汉加载:

这种方式作者在很多资料上都有看到,但是实际中很少使用,而且这种方式在Java早期版本中是有缺陷的,详细的可以参考IBM的大牛的文章【 http://www.ibm.com/developerworks/cn/java/j-dcl.html 】。

public class Singleton_doublecheck
{
	private static volatile Singleton_doublecheck instance = null;

	private Singleton_doublecheck(){}

	public static Singleton_doublecheck getInstance()
	{
		if (null == instance)
		{
			synchronized (Singleton_doublecheck.class)
			{
				if (null == instance)
				{
					instance = new Singleton_doublecheck();
				}
				return instance;
			}
		}
		return instance;
	}

	public void sayHello()
	{
		System.out.println("Hello from Singleton_doublecheck");
	}
}

5)登记式单例:

作者并没有接触过这种单例模式,就现不在此处进行备份了。

单例模式的两个注意点:

1)不同类加载器的问题。

private static Class getClass(String classname)  
                                         throws ClassNotFoundException { 
      ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); 
  
      if(classLoader == null) 
         classLoader = Singleton.class.getClassLoader(); 
  
      return (classLoader.loadClass(classname)); 
   } 
} 

2)Serializable接口问题。

public class Singleton implements java.io.Serializable {   
   public static Singleton INSTANCE = new Singleton();   
    
   protected Singleton() {   
      
   }   
   private Object readResolve() {   
            return INSTANCE;   
      }  
} 

 部分代码参考:

http://cantellow.iteye.com/blog/838473

http://calmness.iteye.com/blog/60179 】 

发表评论

6 + 11 =

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据