第一种(懒汉,线程不安全)
public class Singleton
{
private static Singleton instance;
private Singleton()
{
}
public static Singleton getInstance()
{
if(null == instance)
{
instance = new Singleton();
}
return intance;
}
}
这种写法lazy loading很明显,但致命的是在多线程不能正常工作。
第二种(懒汉,线程安全)
public class Singleton
{
private static Singleton instance;
private Singleton()
{
}
public static synchronized Singleton getInstance()
{
if(null == instance)
{
instance = new Singleton();
}
return intance;
}
}
这种写法能够在多线程中很好的工作,而且看起来它齐备很好的lazy loading,但是效率很低
第三种(饿汉)
public class Singleton
{
private static Singleton instance = new Singleton();
private Singleton()
{
}
public static Singleton getInstance()
{
return intance;
}
}
这种方式基于classloader机制避免了多线程的同步问题,不过instance在类装载时就实例化,没有达到lazy loading的效果。
第四种(静态内部类)
public class Singleton
{
private Singleton()
{
}
public static Singleton getInstance()
{
return SingletonHolder.INSTANCE;
}
priate static class SingletonHolder
{
private static final Singleton INSTANCE = new Singleton();
}
}
这种方式同样利用classloader的机制来保证初始化instance是线程安全的,并且是lazy loading的
第五种(枚举)
public enum Singleton
{
INSTANCE;
public oid whateverMethod()
{
}
}
这种方式是Effectie Java作者Josh Bloch提倡的方式,它不仅能避免多线程同步问题,而且还能防止反序列化后重新创建新的对象,可谓是很坚强的壁垒。不过1.5才引入的enum特性,用这种方式不免让人觉得生疏。
第六种(双重校验锁)
public class Singleton
{
private volatile static Singleton singleton;
public static Singleton getSingleton()
{
if(singleton == null)
{
synchronized(Singleton.class)
{
if(singleton == null)
{
singleton = new Singleton();
}
}
}
}
return singleton;
}
在JDK1.5之后,该方法才能正常达到单例效果
总结
有两个问题需要注意:
1、如果单例由不同的类装载器装入,那便有可能存在多个单例类的实例。假定不是远端存取,例如一些servlet容器对每个servlet使用完全不同的类装载器,这样的话如果有两个servlet访问一个单例类,他们就都会有各自的实例。
2、如果Singleton实现了java.io.Serializable接口,那么这个类的实例就可能被序列化和复原。不管怎样,如果你序列化一个单例类的对象,接下来复原多个该对象,就会有多个单例类的实例
对第一个问题的修复办法是:
private static Class getClass(String classname) throws ClassNotFoundException
{
ClassLoader loader = Thread.currentThread().getContextClassLoader();
if(null == loader)
{
loader = Singleton.class.getClassLoader();
}
return loader.loadClass(classname);
}
对第二个问题的修复办法是:
public class Singleton implements java.io.Serializable
{
public static Singleton INTANCE = new Singleton();
private Singleton()
{
}
private Object readResolve()
{
return INSTANCE;
}
}
分享到:
相关推荐
自己总结的6中单例模式的写法,也有测试类,可以试验下,自己稍微修改一下后,验证安全性,纯粹为学习,建议可提
此文档为Tom老师的公开课的单例的7种写法的一个文档,充分分析单例模式,值得对设计模式有研究的童鞋下下来好好看看
android资料 单例模式的八种写法比较 单例模式是一种常用的软件设计模式,其定义是单例对象的类只能允许一个实例存在。
单例模式的七种写法: 1.第一种(懒汉,线程不安全) 2.第二种(懒汉,线程安全) 3.第三种(饿汉) .....
java单例模式开发的7中写法,网上搜索的,可以看看
深入分析java单例模式什么是单例模式单例模式的常见写法一、饿汉式单例优点缺点示例二、懒汉式单例示例1(普通写法)示例2(synchronized写法)示例3(DCL写法)示例4(内部类写法)三、注册式单例示例1(容器式)示例2(枚举式...
NULL 博文链接:https://kaka100.iteye.com/blog/1060519
JavaSE单例模式各种写法单例模式
单例的多种写法效率和方法同步比较说明,常用懒汉和饥汉模式等
第一种(懒汉,线程不安全): 1 public class Singleton { 2 private static Singleton instance; 3 private Singleton (){} 4 public static Singleton getInstance() { 5 if ...
1、掌握单例模式的应用场景。 2、掌握 IDEA 环境下的多线程调试方式。 3、掌握保证线程安全的单例模式策略。 4、掌握反射暴力攻击单例解决方案及原理分析。...5、序列化破坏单例的原理及...6、掌握常见的单例模式写法。
在java中,单例有很多种写法,面试时,手写代码环节,除了写算法题,有时候也会让手写单例模式,这里记录一下单例的几种写法和优缺点。需要的朋友可以参考下
2、单例类必须自己创建自己的唯一实例 3、单例类必须给所有其他对象提供这一实例 2、资源加载和性能:饿汉式在类创建的同时就实例化一个静态对象出来,不管之后会不会
unity中在场景切换时需要经常数据分享并处理,在此分享给大家利用C#模式和Unity模式分别实现的单例共享数据
主要介绍了IOS 中两种单例模式的写法实例详解的相关资料,需要的朋友可以参考下
static静态关键字和单例模式
Objective-c 单例模式的完整书写方式,用了很久的单例模式了,却发现singleton的用法也是蛮有讲究的。不过一般情况下,即使不书写完整的单例,也不会出现什么意外情况。。
【Java面试题】单例的写法