论坛首页 Java企业应用论坛

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

浏览 9383 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (9) :: 隐藏帖 (0)
作者 正文
   发表时间:2009-09-26   最后修改: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;
  }
}
1 请登录后投票
   发表时间:2010-01-06  
这个完美的答案我有点不解,这个方案完美在哪里?

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

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

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

如果有同步,那每次取得单例对象时都会进行一次同步。好像并有没什么优势。。。
0 请登录后投票
   发表时间: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
0 请登录后投票
   发表时间: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相关文档后得出的结论,请大家指正。
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics