设计模式 -- 单例模式(饿汉,懒汉模式与多线程下的使用)
单例模式:
单例模式就是在应用程序中只创建一个该类的对象。又分为饿汉模式和懒汉模式。实现套路也就是只提供私有构造函数,然后提供公有的 getInstance 方法。
饿汉模式:也就是一开始就创建该对象。
懒汉模式:等到需要用到的时候才创建该对象。
饿汉模式
单例模式实现起来并不困难,但是有时候如果用在多线程环境下,那么就可能会出问题。例如上面的实现方法其实都没有做同步处理。
多线程2:双重判断
基本概念:分饿汉,懒汉模式。实现:只提供私有构造函数 与 getInstance 方法。
普通的单例模式的实现不支持多线程环境,若需支持则要结合 synchronized 或者 lock 等多线程处理方式。
synchronized是托管给JVM执行的,而lock是Java写的控制锁的代码。在Java1.5中,synchronize是性能低效的。因为这是一个重量级操作,需要调用操作接口,导致有可能加锁消耗的系统时间比加锁以外的操作还多。相比之下使用Java提供的Lock对象,性能更高一些。但是到了Java1.6,发生了变化。synchronize在语义上很清晰,可以进行很多优化,有适应自旋,锁消除,锁粗化,轻量级锁,偏向锁等等。导致在Java1.6上synchronize的性能并不比Lock差。官方也表示,他们也更支持synchronize,在未来的版本中还有优化余地。
单例模式:
单例模式就是在应用程序中只创建一个该类的对象。又分为饿汉模式和懒汉模式。实现套路也就是只提供私有构造函数,然后提供公有的 getInstance 方法。
饿汉模式:也就是一开始就创建该对象。
懒汉模式:等到需要用到的时候才创建该对象。
饿汉模式
public class Singleton {
private static Singleton singleton = new Singleton();
private Singleton(){};
public static Singleton getInstance(){
return singleton;
}
}
懒汉模式public class Singleton {
private static Singleton singleton;
private Singleton(){};
public static Singleton getInstance(){
if(singleton == null)
singleton = new Singleton();
return singleton;
}
}
单例模式与多线程单例模式实现起来并不困难,但是有时候如果用在多线程环境下,那么就可能会出问题。例如上面的实现方法其实都没有做同步处理。
多线程1 : synchronized
public static synchronized Singleton getInstance(){
if(singleton == null)
singleton = new Singleton();
return singleton;
}
这种实现方式比较粗糙,在使用的时候,每次都需要加锁,理论上说,创建完后,可以允许多线程读。多线程2:双重判断
public class Singleton {
private static Singleton singleton;
private static Lock lock = new ReentrantLock();
private Singleton(){};
public static Singleton getInstance(){
if(singleton == null){
lock.lock();
try {
if(singleton == null){
singleton = new Singleton();
}
} finally{
lock.unlock();
}
}
return singleton;
}
}
总结基本概念:分饿汉,懒汉模式。实现:只提供私有构造函数 与 getInstance 方法。
普通的单例模式的实现不支持多线程环境,若需支持则要结合 synchronized 或者 lock 等多线程处理方式。
synchronized是托管给JVM执行的,而lock是Java写的控制锁的代码。在Java1.5中,synchronize是性能低效的。因为这是一个重量级操作,需要调用操作接口,导致有可能加锁消耗的系统时间比加锁以外的操作还多。相比之下使用Java提供的Lock对象,性能更高一些。但是到了Java1.6,发生了变化。synchronize在语义上很清晰,可以进行很多优化,有适应自旋,锁消除,锁粗化,轻量级锁,偏向锁等等。导致在Java1.6上synchronize的性能并不比Lock差。官方也表示,他们也更支持synchronize,在未来的版本中还有优化余地。