6 单例模式与线程池

做j2ee如果不懂单例模式和线程池慢慢就是白学了。

线程池到处都能看到,httpsession,数据库连接池,redis连接池,MQ连接池。。。

使用场景:频繁使用且创建本消耗高

多线程环境下,使用场景随处可见...

 

 
饿汉式和懒汉式
名词懒得解释了。。。
懒汉式需要双重锁定
饿汉式没线程安全问题

1,双锁单例模式,懒汉式

 
 1  /// 定义一个全局访问点
 2         /// 设置为静态方法
 3         /// 则在类的外部便无需实例化就可以调用该方法
 4         public static Singleton GetInstance()
 5         {
 6             //这里可以保证只实例化一次
 7             //即在第一次调用时实例化
 8             //以后调用便不会再实例化
 9             //第一重 singleton == null
10             if (singleton == null)
11             {
12                 lock (syncObject)
13                 {
14                     //第二重 singleton == null
15                     if (singleton == null)
16                     {
17                         singleton = new Singleton();
18                     }
19                 }
20             }
21             return singleton;
22         }
23 
24  
View Code

 

2,静态工厂方法,也是饿汉式最简单写法。

 1 public class Singleton{
 2     //initailzed during class loading
 3     private static final Singleton INSTANCE = new Singleton();
 4   
 5     //to prevent creating another instance of Singleton
 6     private Singleton(){}
 7 
 8     public static Singleton getSingleton(){
 9         return INSTANCE;
10     }
11 }
View Code

 

 

spring配置的sessionFactory \DataSource都是默认单例。例如:

 

1        //获取spring创建的bean对象
2     public synchronized static MyCache getInstance() {
3 
4       return  ServletUtil.getApplicationContext().getBean( MyCache.class);
5 
6     }

3,序列化对象,枚举实现单例基本是炫技,

 

 

最后:

单核心的多线程,不会有2个线程同时进入if判断,本质还是一个线程。但多核心的,就完全可能2线程同时一个if判断。

单例的范围:

本文的单例的范围是AppDomain. 
要在一个AppDomain中保持单例的办法是, 只在Main()中new这个对象一次, 然后把这个对象的引用赋值给所用使用它的对象.

如果要在操作系统中实现单例, 就需要使用Mutex(对象互斥锁)了。一个程序只允许运行一个实例,即不能多开。在我写C#桌面程序时经常用到。
如果要在Internet上实现单例, 可以使用URL唯一.

 

 

 

posted @ 2016-05-19 23:42  一名IT老农  阅读(2641)  评论(0编辑  收藏  举报