一个简简单单的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
分享到:
相关推荐
线程唯一的单例模式,又称为线程局部单例,是指在同一个线程内保证单例的唯一性,而在不同线程之间可以有各自的实例。实现线程唯一单例通常可以通过使用`ThreadLocal`变量。`ThreadLocal`为每个线程都维护了一个独立...
"设计模式单例模式和工厂模式综合应用"的主题聚焦于两种常用的设计模式:单例模式和工厂模式,并探讨它们如何协同工作来实现高效、灵活的代码结构。这个主题尤其适用于Java编程语言,因为Java的面向对象特性使得设计...
单例模式是软件设计模式中的一种经典模式,它保证了类只有一个实例存在,并提供一个全局访问点。在Java等面向对象编程语言中,单例模式常...同时,也可以尝试自己编写并测试不同的单例实现,以加深对单例模式的理解。
在“pattern”这个压缩包中,可能包含了一些用于展示不同单例模式实现方式的代码,以及针对上述调试步骤的示例。通过研究这些代码,开发者可以更好地理解单例模式的工作原理,以及如何在实际项目中高效、安全地使用...
这个讲的是单例模式的多种不同实现方式,希望对单例感兴趣的同学看看
在C++编程中,单例模式是一种常用的软件设计模式,它保证一个类只有一个实例,并提供一个全局访问点。在这个特定的场景中,我们讨论的是一个实现了单例模式的日志类,该类专为多线程环境设计,具备日志等级控制、...
通过`SingletonFactory`,我们可以轻松地在不同的单例模式间切换,同时也可以注册自定义的单例对象。例如,如果需要自定义一个数据库连接池的单例,可以这样使用: ```java public class CustomSingleton { ...
由于每次HTTP请求都会触发一个独立的处理流程,因此采用单例模式来实现HttpApplication能够保证在不同请求之间共享同一个实例,从而提高整体性能。 #### 三、总结 通过对上述应用场景的分析,我们可以总结出单例...
- **类加载器的影响**:不同的类加载器可能会加载同一类的不同实例,导致单例模式失效。 - **序列化的影响**:如果单例类实现了 `Serializable` 接口,那么通过序列化和反序列化可能会产生新的实例,这同样会破坏...
当单例模式与命令模式结合时,我们可以创建一个管理所有游戏规则的单例类,这个类可以根据配置信息动态地加载和执行不同的游戏规则。这里使用反射机制,可以在运行时根据配置文件加载相应的类,实现了代码与配置的...
在给定的标题和描述中,我们关注的是两种重要的设计模式:单例模式和观察者模式。 首先,让我们深入了解单例模式。单例模式是一种确保一个类只有一个实例,并提供全局访问点的设计模式。这种模式在资源管理、缓存、...
不同的单例模式各有优劣,开发者应根据实际情况选择最适合的方式。例如,在需要提前加载的场合,可以选择饿汉式;而在资源占用敏感或需要按需加载的情况下,则更适合使用懒汉式或双重检查锁方式。
在ACCP V4.0的讲解中,提到了五种不同的单例模式实现方式: 1. **简单实现**: 这是最基础的实现方式,通过私有的构造函数防止外部直接实例化,然后通过静态的`getInstance()`方法返回唯一的实例。但是这种方式在...
单例模式和工厂模式是两种常见的软件设计模式,在面向对象编程中扮演着重要的角色。它们都是为了解决特定的问题而提出的解决方案,但有着不同的应用场景和设计思路。 **单例模式** 是一种限制类实例化次数的模式,...
工具开发时,例如配置管理工具,可能会有一个全局的配置管理器,它使用单例模式保证在整个应用中只存在一个实例,同时可以灵活地切换不同的配置策略。 总的来说,策略模式和单例模式都是为了解决特定问题而设计的,...
单例模式是一种设计模式,它保证了一个类只有一个实例,并提供一个全局访问点。这种模式在 PHP 中尤其适用于控制共享资源,例如数据库连接、缓存服务或者配置对象,确保在整个应用程序中这些资源只被初始化一次。 ...
在本文中,我们将深入探讨三种工厂设计模式——简单工厂模式、抽象工厂模式和工厂方法模式,以及两种单例模式——饿汉单例模式和懒汉单例模式。这些模式都是面向对象设计中的重要组成部分,对于理解和构建可维护、可...
单例模式是软件设计模式中的一个经典模式,它在Java编程中被广泛应用。单例模式的核心思想是确保一个类...通过这些代码,你可以亲手运行并观察不同实现方式的效果,进一步理解单例模式的工作原理及其在Java中的应用。
单例模式是其中之一,它确保一个类只有一个实例,并提供一个全局访问点。在这个场景中,我们讨论的是一个使用Python实现的单例模式日志记录器。日志记录器是程序中用于记录运行时信息的重要工具,它帮助开发者追踪...