当前访客身份:游客 [ 登录 | 加入开源中国 ]

代码分享

当前位置:
代码分享 » Java  » 编程基础
分享到: 
收藏 +0
1
Java中的五种单例模式实现方法
标签: 设计模式

代码片段(1) [全屏查看所有代码]

1. [代码]Java中的五种单例模式实现方法     跳至 [1] [全屏预览]

package singleton;

/**
 * @author lei
 * 单例模式的五种写法:
 * 1、懒汉
 * 2、恶汉
 * 3、静态内部类
 * 4、枚举
 * 5、双重校验锁
 * 2011-9-6
 */
/**
 *五、 双重校验锁,在当前的内存模型中无效
 */
class LockSingleton{
	private volatile static LockSingleton singleton;
	private LockSingleton(){}
	
	//详见:http://www.ibm.com/developerworks/cn/java/j-dcl.html
	public static LockSingleton getInstance(){
		if(singleton==null){
			synchronized(LockSingleton.class){
				if(singleton==null){
					singleton=new LockSingleton();
				}
			}
		}
		return singleton;
	}
	
}
/**
 * 四、枚举,《Effective Java》作者推荐使用的方法,优点:不仅能避免多线程同步问题,而且还能防止反序列化重新创建新的对象
 */
enum EnumSingleton{
	INSTANCE;
	public void doSomeThing(){
	}
}
/**
 * 三、静态内部类 优点:加载时不会初始化静态变量INSTANCE,因为没有主动使用,达到Lazy loading
 */
class InternalSingleton{
	private static class SingletonHolder{
		private final static  InternalSingleton INSTANCE=new InternalSingleton();
	}	
	private InternalSingleton(){}
	public static InternalSingleton getInstance(){
		return SingletonHolder.INSTANCE;
	}
}
/**
 * 二、恶汉,缺点:没有达到lazy loading的效果
 */
class HungrySingleton{
	private static HungrySingleton singleton=new HungrySingleton();
	private HungrySingleton(){}
	public static HungrySingleton getInstance(){
		return singleton;
	}
}
/**
 * 一、懒汉,常用的写法
 */
class LazySingleton{
	private static LazySingleton singleton;
	private LazySingleton(){
	}
	public static LazySingleton getInstance(){
		if(singleton==null){
			singleton=new LazySingleton();
		}
		return singleton;
	}	
}


开源中国-程序员在线工具:Git代码托管 API文档大全(120+) JS在线编辑演示 二维码 更多»

发表评论 回到顶部 网友评论(16)

  • 1楼:游客 发表于 2011-09-06 13:03 回复此评论
    不得不说,我是懒汉。
  • 2楼:磊神Ray 发表于 2011-09-06 13:17 回复此评论
    我比较喜欢“静态内部类”的方式,线程安全且达到了lazy loading的效果。而”恶汉”用起来简便。
  • 3楼:Holt_Vong 发表于 2011-09-06 13:38 回复此评论
    双重校验锁...高级啊
  • 4楼:_bill 发表于 2011-09-07 04:37 回复此评论
    双重校验锁在Java中行不通
  • 5楼:磊神Ray 发表于 2011-09-07 09:52 回复此评论

    引用来自“_bill”的评论

    双重校验锁在Java中行不通
    是的,在当前的内存模型中,双重校验锁是无效的,详见http://www.ibm.com/developerworks/cn/java/j-dcl.html
  • 6楼:Shardon 发表于 2011-09-13 17:22 回复此评论
    双重校验锁?么用过。看到被我直接删了。
  • 7楼:70岁 发表于 2012-01-13 14:03 回复此评论
    没有看懂枚举的那种方式,求解!
  • 8楼:wugang789 发表于 2012-08-20 21:39 回复此评论
    枚举?
  • 9楼:851228082 发表于 2014-02-27 15:54 回复此评论
    懒汉模式,是因为,get的时候才创建?
    饿汉模式,是因为,加载类的时候就创建?
  • 10楼:851228082 发表于 2014-04-16 14:50 回复此评论
    第一种,懒汉模式,在多线程模式下,会存在问题吧。 第一种,懒汉模式,在多线程模式下,会存在问题吧。
  • 11楼:851228082 发表于 2014-04-16 14:50 回复此评论
    第一种,懒汉模式,在多线程模式下,会存在问题吧。
  • 12楼:黄四洲 发表于 2014-08-21 17:31 回复此评论
    懒汉模式单例类非线程安全getInstance 做同步是最安全的
  • 13楼:车开源 发表于 2015-05-24 17:03 回复此评论
    请问,构建单例对象在需要传递参数初始化 怎么做好?
  • 14楼:palm_ 发表于 2016-01-29 17:31 回复此评论
    枚举方法我觉得声明为抽象方法比较好
  • 15楼:mgic 发表于 2016-04-02 19:24 回复此评论

    引用来自“车开源”的评论

    请问,构建单例对象在需要传递参数初始化 怎么做好?
    其实我一直觉得带参数的这种方式,按说根本就破坏了单例的模式。^_^ 因为你是需要通过参数来初始化单例对象,那么枚举、静态内部类、恶汉模式都不合适。 同时获取单例对象的getInstance方法最好不要带参数。 因此,你的单例对象必须在其他地方生成。可以考虑定义一个公有静态无返回的init()方法,在该方法中生成此单例对象。 下面写一个比较简单的范例,还是参考双check的写法,这回写一个带参数的,LockSingletonWithStringParam类。 public class LockSingletonWithStringParam { private volatile static LockSingletonWithStringParam singleton; private LockSingletonWithStringParam(){ } private LockSingletonWithStringParam(String param){ //do LockSingletonWithStringParam init work through param. } public static void init(String param){ //do something. if(singleton==null){ synchronized(LockSingletonWithStringParam.class){ if(singleton==null){ singleton=new LockSingletonWithStringParam(param); } } } } public static LockSingletonWithStringParam getInstance(){ return singleton; } } 看到了吧。调用getinstance之前需要通过参数进行init,所以说严格来讲这不是单例。。。
  • 16楼:wenhaoran 发表于 2016-09-19 10:13 回复此评论
    可串行化的单列还是没有
开源从代码分享开始 分享代码
磊神Ray的其它代码 全部(32)...