做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
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 }
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#桌面程序时经常用到。
要在一个AppDomain中保持单例的办法是, 只在Main()中new这个对象一次, 然后把这个对象的引用赋值给所用使用它的对象.
如果要在操作系统中实现单例, 就需要使用Mutex(对象互斥锁)了。一个程序只允许运行一个实例,即不能多开。在我写C#桌面程序时经常用到。
如果要在Internet上实现单例, 可以使用URL唯一.