`

不同的单例模式

阅读更多
一个简简单单的singleton经常看到引来很多争论。
只要类里面没得其它的static属性或方法,基本不需要考虑lazy load和thread safe,因为java字节码本来就是延时加载的,下面实现就行了。
public class Singleton { 
    public static final Singleton so = new Singleton(); 
    private Singleton(){} 
} 

或者
public class Singleton { 
    private static Singleton so = new Singleton(); 
    private Singleton(){} 
    public static Singleton getInstance {return so;} 
} 

如果class Singleton里面有其它static属性或方法(这种情况几乎没有或者可以避免),这才考虑需不需要延时加载singleton对象,如果这些情况你都遇上了又确实不能忍受提前实例化。那就用holder class或double check(可以参考effective java(2e)中的item 71)。


下面是一个对单例的例子,有4中形式,转自一个回复,感觉好,自己就记录下来了,留给别人学习:
/**
 * @author lee
 * @date Mar 5, 201210:09:12 AM
 * @version V1.0
 * @todo 单例模式属于对象创建型模式,其意图是保证一个类仅有一个实例,并提供一个访问它的全局访问点
 */
public class Singleton {
	private static Singleton instance;
	private static Singleton instance1=new Singleton();
	private static Singleton instance2;
	private static Singleton instance3;
	private volatile static Singleton instance4;
	//私有构造方法,避免外部创建实例
	private Singleton(){
	}
	//懒汉式单例>当需要的时候,并且发现没有实例的时候,才去初始化. 多线程下这种单例模式是起不到效果的
	public static Singleton getInstance(){
		if(instance==null){
			threadSleep();
			instance=new Singleton();
		}
		return instance;
	}
	//饿汉式单例>管你需要不需要,反正我是饿了,类加载的时候就已经初始化,没有起到延迟加载的效果
	public static Singleton getInstance1(){
		return instance1;
	}
	//对懒汉式进行同步,牺牲了性能,同步的原则应该是尽量对代码块同步,不要对整个方法同步
	public static synchronized Singleton getInstance2(){
		if(instance2==null){
			threadSleep();
			instance2=new Singleton();
		}
		return instance2;
	}
	//双重检查加锁DCL(double checking lock),只在第一次调用getInstance()时才要同步,提高性能
	public static Singleton getInstance3(){
		if(instance3==null){
			threadSleep();
			synchronized (Singleton.class) {
				if(instance3==null){
					instance3=new Singleton();
				}
			}
		}
		return instance3;
	}
	
	public static Singleton getInstance4(){
		if(instance4==null){
			threadSleep();
			synchronized (Singleton.class) {
				if(instance4==null){
					instance4=new Singleton();
				}
			}
		}
		return instance4;
	}
	//让当前线程休眠1秒,模拟多个线程同时访问instance==null之后的临界情况
	public static void threadSleep(){
		try {
			System.out.println("当前线程休眠1秒!");
			Thread.currentThread().sleep(1000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
}


上面几种是常见的单例写法,下面分别弄几个线程测试一下,
public class ThreadTest extends Thread {
	
	@Override
	public void run() {
		Singleton s=Singleton.getInstance();
		System.out.println(s.toString());
		
		/*Singleton s1=Singleton.getInstance1();
		System.out.println(s1.toString());*/
		
		/*Singleton s2=Singleton.getInstance2();
		System.out.println(s2.toString());*/
		
		/*Singleton s3=Singleton.getInstance3();
		System.out.println(s3.toString());*/
	}
	public static void main(String[] args) {	
		for(int i=0;i<3;i++){
			ThreadTest test=new ThreadTest();
			test.start();
		}		
	}
}


把RUN方法里的注释,去掉,一次执行一个方法,发现除了第一个在多线程环境下不能实现真正的单例,其他的方法都是可以的。。。

网上有说DCL方法在JAVA中也不能实现真正的单例,不过,这测试结果好像也是可以的。
对单例的讨论过多,现在就到这吧,还是应用上的才是王道。
  • 大小: 14.2 KB
  • 大小: 14 KB
分享到:
评论

相关推荐

    Java单例模式深入理解

    不同单例模式的详细讲解,了解使用单例的最佳方式。

    单例模式代码实现

    这个讲的是单例模式的多种不同实现方式,希望对单例感兴趣的同学看看

    单例模式,single

    典型的情况是,那些对象的类型被遍及一个软件系统的不同对象访问,因此需要一个全局的访问指针,这便是众所周知的单例模式的应用。当然这只有在你确信你不再需要任何多于一个的实例的情况下。 单例模式的用意在于前...

    单例模式.ppt

    单例模式,您能写出几个呢?这个PPT将为你全面阐述5种不同形式的单例模式。

    单例模式(饿汉模式、懒汉模式、DCL单例模式、枚举)

    饿汉模式、懒汉模式、DCL单例模式、枚举;不同情况下使用不同的单例创建模式

    单例模式与装饰着模式.md

    通过学习java 简单总结单例模式与装饰者模式,做一下入门总结,主要讲述单例模式中饿汉式与懒汉式的相同点与不同点,方便理解记忆。

    单例模式案例和笔记,通过案例来了解单例模式

    Java一共有23种设计模式,单例模式就是指一个类只有一个实例,且该类能...项目中一般可以通过单例模式来获取同一个对象来调用工具方法,这样的好处是节约内存资源,我没有必要创建多个不同的对象,因为这样消耗内存资源

    单例模式 工厂模式DEMO

    1、单例模式 结论:单例模式可以把数据封装在对象里,操作对象;而静态类是把数据封装在类里,操作类。单例模式中,数据只有在对象存在的时候才能操作;而静态类中,数据可以直接通过静态类点出来操作。 2、工厂模式...

    关于redis四种不同模式(单例\主从\哨兵\集群)java示例代码项目下载(含完整依赖包).txt

    该项目提供正对redis四种不同模式 (单例模式/主从模式/哨兵模式/集群模式)demo代码示例,项目结构如图所示,其中cluster目录下JedisCulsterTest.java是集群示例、jedis下JedisClientTest.java是单例示例、sentinel...

    Kotlin中的5种单例模式示例详解

    所以对不同单例模式的实现进行了分别探讨。主要单例模式实现如下: 饿汉式 懒汉式 线程安全的懒汉式 双重校验锁式 静态内部类式 PS:该篇文章不讨论单例模式的运用场景与各种模式下的单例模式的优缺点。只讨论在...

    【JavaScript源代码】JS实现单例模式的6种方案汇总.docx

    就是一个全局变量,在团队开发中,为了实现一些相似的功能,比如不同页面之间的表单验证,可能需求是不一样的,但是呢命名可能一样,这时就会产生冲突,这时候单例模式就能很好的解决这个问题。  一个实例只生产一...

    Java设计模式之单例模式及其应用

    一、 单例模式概述  Java中单例模式的定义是:一个类只有一个实例,而且自行实例化并且向整个系统提供这个实例。  优点:由于单例模式在内存中只有一个实例,减少了内存开支和系统的性能开销;单例模式可以避免...

    singleton_单例模式_java_设计模式_

    java设计模式,单例模式的不同实现方式

    最全的单例模式j(java实现),下到就是赚到!

    最近在学习多线程相关知识,同时加深了对单例的理解,从并发的角度学习到了不同的单列模式,提供出来供大家一起学习

    ConardLi#awesome-coding-js#单例模式1

    创建对象和管理单例的职责被分布在两个不同的方法中,这两个方法组合起来才具有单例模式的威力。使用闭包实现:var Singleton = function(nam

    单例模式的5种设计.docx

    单例模式,顾名思义就是只有一个实例,并且她自己负责创建自己的对象,这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。下面我们来看下有哪几种实现方式吧。

    Qt多工程调用单例实现,带线程锁

    本资源包含有三个子项目工程,实现的是通过DataSource做数据管理,DataSource是一个单例类,做了测试在不同类中调用单例函数依旧能保证唯一性

    PHP单例模式定义与使用实例详解

    先简单的介绍一下单例模式。单例模式就是在应用程序中保持某一个类实例只存在一个,而且不可以受外部环境的影响而生成这个类的第二个实例。它的优点,实际点见,如果在WEB开发中,保持单一个数据操作类实例的存在,...

    PHP常用的三种设计模式

    一、首先来看,单例模式 所谓单例模式,即在应用程序中只会有这个类的一个实例存在。 通常单例模式用在仅允许数据库访问对象的实例中,从而防止打开多个数据库连接。 一个单例类应包括以下几点: 和普通类不同,单例...

    设计模式课程设计---使用6个不同的设计模式完成绘图系统(java)

    运用到的设计模式有备忘录模式,迭代器模式,简单工厂模式,状态模式,模版方法模式,单例模式。 资源包含项目文件(eclipse)以及系统说明(docx文件),系统说明中说明了为什么要使用该模式,使用该模式有什么好处...

Global site tag (gtag.js) - Google Analytics