`

不同的单例模式

阅读更多
一个简简单单的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
分享到:
评论

相关推荐

    43丨单例模式(下):如何设计实现一个集群环境下的分布式单例模式?1

    线程唯一的单例模式,又称为线程局部单例,是指在同一个线程内保证单例的唯一性,而在不同线程之间可以有各自的实例。实现线程唯一单例通常可以通过使用`ThreadLocal`变量。`ThreadLocal`为每个线程都维护了一个独立...

    设计模式单例模式和工厂模式综合应用

    "设计模式单例模式和工厂模式综合应用"的主题聚焦于两种常用的设计模式:单例模式和工厂模式,并探讨它们如何协同工作来实现高效、灵活的代码结构。这个主题尤其适用于Java编程语言,因为Java的面向对象特性使得设计...

    设计模式之单例模式(结合工厂模式)

    单例模式是软件设计模式中的一种经典模式,它保证了类只有一个实例存在,并提供一个全局访问点。在Java等面向对象编程语言中,单例模式常...同时,也可以尝试自己编写并测试不同的单例实现,以加深对单例模式的理解。

    IOS单例模式调试代码

    在“pattern”这个压缩包中,可能包含了一些用于展示不同单例模式实现方式的代码,以及针对上述调试步骤的示例。通过研究这些代码,开发者可以更好地理解单例模式的工作原理,以及如何在实际项目中高效、安全地使用...

    单例模式代码实现

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

    c++单例模式线程日志类

    在C++编程中,单例模式是一种常用的软件设计模式,它保证一个类只有一个实例,并提供一个全局访问点。在这个特定的场景中,我们讨论的是一个实现了单例模式的日志类,该类专为多线程环境设计,具备日志等级控制、...

    Java 单例模式 工具类

    通过`SingletonFactory`,我们可以轻松地在不同的单例模式间切换,同时也可以注册自定义的单例对象。例如,如果需要自定义一个数据库连接池的单例,可以这样使用: ```java public class CustomSingleton { ...

    单例模式应用场景

    由于每次HTTP请求都会触发一个独立的处理流程,因此采用单例模式来实现HttpApplication能够保证在不同请求之间共享同一个实例,从而提高整体性能。 #### 三、总结 通过对上述应用场景的分析,我们可以总结出单例...

    单例模式,single

    - **类加载器的影响**:不同的类加载器可能会加载同一类的不同实例,导致单例模式失效。 - **序列化的影响**:如果单例类实现了 `Serializable` 接口,那么通过序列化和反序列化可能会产生新的实例,这同样会破坏...

    单例模式_命令模式

    当单例模式与命令模式结合时,我们可以创建一个管理所有游戏规则的单例类,这个类可以根据配置信息动态地加载和执行不同的游戏规则。这里使用反射机制,可以在运行时根据配置文件加载相应的类,实现了代码与配置的...

    设计模式 中的 单例模式和观察者模式

    在给定的标题和描述中,我们关注的是两种重要的设计模式:单例模式和观察者模式。 首先,让我们深入了解单例模式。单例模式是一种确保一个类只有一个实例,并提供全局访问点的设计模式。这种模式在资源管理、缓存、...

    Java单例模式应用研究.pdf

    不同的单例模式各有优劣,开发者应根据实际情况选择最适合的方式。例如,在需要提前加载的场合,可以选择饿汉式;而在资源占用敏感或需要按需加载的情况下,则更适合使用懒汉式或双重检查锁方式。

    单例模式.ppt

    在ACCP V4.0的讲解中,提到了五种不同的单例模式实现方式: 1. **简单实现**: 这是最基础的实现方式,通过私有的构造函数防止外部直接实例化,然后通过静态的`getInstance()`方法返回唯一的实例。但是这种方式在...

    单例模式和工厂模式代码

    单例模式和工厂模式是两种常见的软件设计模式,在面向对象编程中扮演着重要的角色。它们都是为了解决特定的问题而提出的解决方案,但有着不同的应用场景和设计思路。 **单例模式** 是一种限制类实例化次数的模式,...

    设计模式——策略模式 & 单例模式

    工具开发时,例如配置管理工具,可能会有一个全局的配置管理器,它使用单例模式保证在整个应用中只存在一个实例,同时可以灵活地切换不同的配置策略。 总的来说,策略模式和单例模式都是为了解决特定问题而设计的,...

    php单例模式和工厂模式

    单例模式是一种设计模式,它保证了一个类只有一个实例,并提供一个全局访问点。这种模式在 PHP 中尤其适用于控制共享资源,例如数据库连接、缓存服务或者配置对象,确保在整个应用程序中这些资源只被初始化一次。 ...

    三种工厂设计模式和两种单例模式

    在本文中,我们将深入探讨三种工厂设计模式——简单工厂模式、抽象工厂模式和工厂方法模式,以及两种单例模式——饿汉单例模式和懒汉单例模式。这些模式都是面向对象设计中的重要组成部分,对于理解和构建可维护、可...

    单例模式代码.rar

    单例模式是软件设计模式中的一个经典模式,它在Java编程中被广泛应用。单例模式的核心思想是确保一个类...通过这些代码,你可以亲手运行并观察不同实现方式的效果,进一步理解单例模式的工作原理及其在Java中的应用。

    使用python写的单例模式日志记录器(设计模式之单例模式)

    单例模式是其中之一,它确保一个类只有一个实例,并提供一个全局访问点。在这个场景中,我们讨论的是一个使用Python实现的单例模式日志记录器。日志记录器是程序中用于记录运行时信息的重要工具,它帮助开发者追踪...

Global site tag (gtag.js) - Google Analytics