`
janeky
  • 浏览: 365968 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

Java设计模式-之Singleton单例模式

阅读更多

Singleton (单例模式)

 

Intent Ensure a class only has one instance , and provide a global point of access of it.

 

瞎谈:就是保证一个类只有一个实例,并且提供一个全局可访问的点。打个比方,广州限制每户人家养狗,但是只能养一条。一开始你没有狗,你去买一条。若干年后,狗不行失踪了。你为了填补寂寞的空虚,别人又送你一条(或者还是你自己买的)。我们不关注你的狗来源,只保证你家的狗每时每刻就一条。你为了确保以后养狗方便,就到保险公司办了保险,他们承诺,你的狗要是出现意外事故,他们负责陪一条给你。从此,你自由了,狗的事情交给别人了,而且别人也保证只给一条给你。

 

正经:很多时候我们要保证类的实例只有一个。我们可能在自己的代码中判断需要的类的实例有无,无就new一个。这样看似不错。问题是,你用到这个类的地方有n个,这样你就需要n个判断。为什么不把这个职责交给类本身呢?然后让类提供一个接口访问

 

代码实现:

 

public class Singleton

{

private static Singleton singleton=null;

private Singleton()

{}

public static Singleton instance()

{

   if(singleton==null)

      singleton = new Singleton();

   return singleton

      return singleton;

}

}

 

有无问题:碰上多线程怎么办?凉拌了。加锁吧,或者。。。前人总结的经验,有3中方法

1.       直接加锁

public class Singleton

{

private static Singleton singleton=null;

private Singleton()

{}

public static synchronized Singleton instance()

{

   if(singleton==null)

      singleton = new Singleton();

   return singleton

      return singleton;

}

}

2.       早期实例化

public class Singleton

{

private static Singleton singleton = new Singleton();

private Singleton();

public static Singleton getInstance()

{

   return singleton;

}

}

 

3.       双重检测锁

public class Singleton

{

   private volatile static Singleton singleton=null;

   private Singleton(){}

   public static Singleton getInstance()

   {

              if(singleton==null)

        {    synchronized(Singleton.class)

                     {

                           singleton=new Singleton();

                     }

         }

         return singleton;

    }

分享到:
评论
13 楼 llyzq 2010-01-13  
clarkht 写道
以上的Singleton模式的写法都正确,不过了没有一个是最佳的。。。

前面所谈到的Double-Checked Lock模式了,也是有数据并发问题

参考javaworld

lazy initialization and mitigate the synchronizaiton overhead on common code path
[url]
[/url]http://www.javaworld.com/javaworld/jw-11-2001/jw-1116-dcl.html


给你一个完美的

 public class ThreadLocalDCL{
  private static ThreadLocal initHolder = new ThreadLocal();
  
  private static Resource resource = null;
  
  public Resource getResource(){
    if(initHolder.get() == null){
	   synchronized{
	      if(resource == null)
		   resource = new Resource();
		  initHolder.set(Boolean.TRUE);
	   }
	}
	return resource;
  }
}




利用ThreadLocal虽然实现了线程安全,同时效率也比较高,但是由于为每个线程都保留了一个单例对象,势必会占用更多的资源。
而且,这个方案的本质是为每个线程创建一个单例的对象,而不是全局所有的线程。

以上是我自己研究ThreadLocal相关文档后得出的结论,请大家指正。
12 楼 llyzq 2010-01-06  
刚才我在网上查了一下
ThreadLocal和线程同步机制不一样,具体内容如下:

ThreadLocal和线程同步机制相比有什么优势呢?ThreadLocal和线程同步机制都是为了解决多线程中相同变量的访问冲突问题。

在同步机制中,通过对象的锁机制保证同一时间只有一个线程访问变量。这时该变量是多个线程共享的,使用同步机制要求程序慎密地分析什么时候对变量进行读写,什么时候需要锁定某个对象,什么时候释放对象锁等繁杂的问题,程序设计和编写难度相对较大。

而ThreadLocal则从另一个角度来解决多线程的并发访问。ThreadLocal会为每一个线程提供一个独立的变量副本,从而隔离了多个线程对数据的访问冲突。因为每一个线程都拥有自己的变量副本,从而也就没有必要对该变量进行同步了。ThreadLocal提供了线程安全的共享对象,在编写多线程代码时,可以把不安全的变量封装进ThreadLocal。

由于ThreadLocal中可以持有任何类型的对象,低版本JDK所提供的get()返回的是Object对象,需要强制类型转换。但JDK 5.0通过泛型很好的解决了这个问题,在一定程度地简化ThreadLocal的使用,概括起来说,对于多线程资源共享的问题,同步机制采用了“以时间换空间”的方式,而ThreadLocal采用了“以空间换时间”的方式。前者仅提供一份变量,让不同的线程排队访问,而后者为每一个线程都提供了一份变量,因此可以同时访问而互不影响。



本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/canyingwushang/archive/2009/03/01/3946752.aspx
11 楼 llyzq 2010-01-06  
这个完美的答案我有点不解,这个方案完美在哪里?

我的理解如下,不知是否正确。

if(initHolder.get() == null)  是为了减少同步

但ThreadLocal类本身就没有同步么?

如果有同步,那每次取得单例对象时都会进行一次同步。好像并有没什么优势。。。
10 楼 clarkht 2009-09-26  
以上的Singleton模式的写法都正确,不过了没有一个是最佳的。。。

前面所谈到的Double-Checked Lock模式了,也是有数据并发问题

参考javaworld

lazy initialization and mitigate the synchronizaiton overhead on common code path
[url]
[/url]http://www.javaworld.com/javaworld/jw-11-2001/jw-1116-dcl.html


给你一个完美的

 public class ThreadLocalDCL{
  private static ThreadLocal initHolder = new ThreadLocal();
  
  private static Resource resource = null;
  
  public Resource getResource(){
    if(initHolder.get() == null){
	   synchronized{
	      if(resource == null)
		   resource = new Resource();
		  initHolder.set(Boolean.TRUE);
	   }
	}
	return resource;
  }
}
9 楼 wangdgsc 2009-09-25  
在JDK1.6中有枚举(太久没用1.5了,不记得有没有),据说默认就是可序列化并且线程安全的,如果要写单例模式,不如就直接用一个枚举类,多好啊,还自己搞那么多的判断
8 楼 vieri122 2009-09-25  
public class Singleton
{
private static Singleton singleton = new Singleton();
private Singleton();
public static Singleton getInstance()
{
   return singleton;
}
}
喜欢用这个,因为C++同步锁有点麻烦
7 楼 changchunren520 2009-09-25  
<div class="quote_title">anyanyway 写道</div>
<div class="quote_div">
<p>补充一种形式,也是线程安全的:<span id="The_solution_of_Bill_Pugh" class="mw-headline"><span style="color: #ff0000;">The solution of Bill Pugh</span></span></p>
<p> </p>
<pre name="code" class="java"> public class Singleton {
   // Private constructor prevents instantiation from other classes
   private Singleton() {}

   /**
    * SingletonHolder is loaded on the first execution of Singleton.getInstance()
    * or the first access to SingletonHolder.INSTANCE, not before.
    */
   private static class SingletonHolder {
     private static final Singleton INSTANCE = new Singleton();
   }

   public static Singleton getInstance() {
     return SingletonHolder.INSTANCE;
   }
}</pre>
<p> </p>
<p>from:<a href="http://en.wikipedia.org/wiki/Singleton_pattern#The_solution_of_Bill_Pugh">http://en.wikipedia.org/wiki/Singleton_pattern#The_solution_of_Bill_Pugh</a></p>
</div>
<p><br>这种方式的确在网上有不少美誉,不过我在项目中到时,它的性能差的很多,速度要比正常单例出来的对象慢</p>
6 楼 jasstion 2009-09-24  
如果别人使用的类是持续性的,比如session,单单用synchronized肯定不行吧,应该再加上一种情况采用ThreadLocal实现同步的方式
5 楼 vvggsky 2009-09-24  
双检锁那个写的有问题

同步里面还要判断以下,不然可能会重复创建!
4 楼 Checkmate 2009-09-24  
代码还行,例子感觉不是非常恰当。
3 楼 lishuaibt 2009-09-21  
还可以再细致一点儿哈,比如阐述一下为什要用单例模式之类的。。。除了所谓的只要一次实例化之类的说辞。。同样用static的话 也能达到同样的效果过啊。。是吧!
2 楼 kaneg 2009-09-20  
不错,这个帖子把Java现有的各种单例模式的实现方式总结的很好
1 楼 anyanyway 2009-09-20  
<p>补充一种形式,也是线程安全的:<span id="The_solution_of_Bill_Pugh" class="mw-headline"><span style="color: #ff0000;">The solution of Bill Pugh</span></span></p>
<p> </p>
<pre name="code" class="java"> public class Singleton {
   // Private constructor prevents instantiation from other classes
   private Singleton() {}

   /**
    * SingletonHolder is loaded on the first execution of Singleton.getInstance()
    * or the first access to SingletonHolder.INSTANCE, not before.
    */
   private static class SingletonHolder {
     private static final Singleton INSTANCE = new Singleton();
   }

   public static Singleton getInstance() {
     return SingletonHolder.INSTANCE;
   }
}</pre>
<p> </p>
<p>from:<a href="http://en.wikipedia.org/wiki/Singleton_pattern#The_solution_of_Bill_Pugh">http://en.wikipedia.org/wiki/Singleton_pattern#The_solution_of_Bill_Pugh</a></p>

相关推荐

    java设计模式----单例模式

    在Java编程语言中,设计模式是一种经过验证的解决常见软件设计问题的最佳实践。单例模式是其中最常用的一种,它的核心思想是确保一个类只有一个实例,并提供全局访问点。单例模式的应用场景包括:控制资源的访问、...

    大话设计模式--Singleton(单例模式)

    单例模式是软件设计模式中的一种经典模式,它在许多场景下被广泛使用,尤其是在需要全局唯一实例的情况下。本文将深入探讨单例模式的概念、作用、实现方式以及其在实际编程中的应用。 单例模式的核心思想是确保一个...

    Java设计模式-单例模式详解

    Java设计模式-单例模式详解 单例模式是 Java 设计模式中的一种常用的设计模式,旨在保证一个类仅有一个实例,并提供一个访问它的全局访问点。单例模式的目的是为了保证在一个进程中,某个类有且仅有一个实例。 ...

    设计模式--单例模式java例子

    单例模式是软件设计模式中的一种经典模式,它在Java编程中被广泛使用。这个模式的主要目的是确保一个类只有一个实例,并提供一个全局访问点。这样做的好处在于可以控制实例的数量,减少资源消耗,同时便于协调整个...

    java设计模式-单例.pdf

    ### Java设计模式——单例模式详解 #### 一、单例模式概述 单例模式是设计模式中的一个重要组成部分,属于创建型模式之一。其主要作用是确保某个类仅有一个实例存在,并提供一个全局访问该实例的方法。这在很多场景...

    java设计模式---诙谐易懂版

    根据给定文件内容,以下是关于Java设计模式的知识点说明: 1. 策略模式(Strategy Pattern)是一种行为设计模式,允许在运行时选择算法的行为。策略模式的意图是定义一系列算法,将每个算法封装起来,并使它们可以...

    Java-设计模式-单例模式-实现源码(简单实现、双重检查锁、静态内部类、枚举类)

    单例模式是软件设计模式中的一种经典模式,其主要目的是保证一个类只有一个实例,并提供一个全局访问点。在Java中,有多种实现单例模式的方法,包括简单实现、双重检查锁定(Double-Checked Locking)、静态内部类和...

    JAVA设计模式-chm版

    Java设计模式是软件开发中的一种最佳实践,它总结了在解决特定问题时程序员们经常采用的有效方法。这个“JAVA设计模式-chm版”资源显然包含了关于Java设计模式的详细信息,便于理解和应用。设计模式是对常见问题的...

    Java常用设计模式(SingleTon、FactoryMethod、AbstractFactory)

    这里我们将深入探讨三种常见的Java设计模式:单例(Singleton)、工厂方法(Factory Method)和抽象工厂(Abstract Factory)。 **单例模式(Singleton)** 单例模式确保一个类只有一个实例,并提供一个全局访问点...

    java Singleton单例模式

    Java中的Singleton(单例模式)是一种常用的软件设计模式,它保证了类只有一个实例,并提供一个全局访问点。这种模式在需要频繁创建和销毁对象的场景中特别有用,因为它可以节省系统资源,例如数据库连接或者线程池...

    设计模式-Java单例模式的各种实现实例

    单例模式(Singleton Pattern)是一种常用的软件设计模式,它保证一个类仅有一个实例,并提供一个访问该实例的全局访问点。这种模式通常用于需要频繁地创建和销毁的对象,以减少系统性能开销。 单例模式的优点: ...

    java单例模式实例

    单例模式是软件设计模式中的一种经典模式,用于确保一个类只有一个实例,并提供一个全局访问点。在Java中,有多种实现单例模式的方法,每种都有其特点和适用场景。接下来,我们将深入探讨这些实现方式。 首先,我们...

    ava常用设计模式-单例模式

    单例模式(Singleton Pattern)是 Java 中最简单的设计模式之一,有以下特点: 1. 单例类只能有一个实例。 2. 单例类必须自己创建自己的唯一实例。 3. 单例类必须给所有其他对象提供这一实例。 单例模式有多种实现...

    设计模式-单例模式

    **设计模式——单例模式** 单例模式是一种广泛应用于软件设计中的创建型设计模式,它的核心思想是确保一个类只有一个实例,并提供一个全局访问点。这样做的好处在于控制共享资源的访问,比如线程安全的数据库连接池...

    常见设计模式-单例模式

    设计模式-单例模式 单例模式是一种常见的设计模式,它的主要作用是确保在内存中仅创建一次对象,并提供一个全局访问点。单例模式有两种类型:饿汉类型和懒汉类型。 饿汉类型的单例模式是在类加载时创建对象,例如...

    JAVA设计模式-day2.pdf

    JAVA设计模式-day2,请的行业大能讲得课程,涉及:创建模式(5种: 1、 工厂方法模式(Factory Method); 2、 抽象工厂模式; 3、 单例模式(Singleton) • 4、 建造者模式(Builder); 5、 原型模式(Prototype...

    Java面向对象(高级)- 单例(Singleton)设计模式

    单例设计模式是面向对象编程中的一种常见设计模式,它的主要目的是确保一个类在整个程序运行期间只有一个实例,并提供全局访问点。这种模式在Java中被广泛应用,尤其是在需要控制资源的共享,如数据库连接池,线程池...

    JAVA设计模式---100%推荐

    JAVA设计模式更是Java开发者必须掌握的核心技能之一,因为它可以提高代码的可读性、可维护性和复用性。这篇名为"JAVA设计模式---100%推荐"的资源,可能是对Java设计模式的深入解析,旨在帮助开发者更好地理解和应用...

    设计模式-单例设计模式

    ### 设计模式—单例设计模式详解 #### 定义 单例模式是一种常见的创建型设计模式,其核心思想在于确保一个类仅有一个实例存在,并且该实例由该类自行创建,随后向整个系统提供这一唯一实例。 #### 类图解析 在设计...

    java设计模式之单例模式.zip

    Java设计模式是面向对象编程中的重要概念,它们是软件开发中经过验证的、解决常见问题的最佳实践。在这些模式中,单例模式是最为广泛使用的一种。单例模式确保一个类只有一个实例,并提供一个全局访问点,使得在整个...

Global site tag (gtag.js) - Google Analytics