单例模式一般分为饿汉模式和懒汉模式。
一般在开发时使用饿汉模式,此方法不需要考虑线程安全问题。
package lh.zjzk;
/**
* 饿汉模式
* @author Administrator
*
*/
public class SingleDemo {
private static final SingleDemo instance = new SingleDemo();
private SingleDemo(){}
public static SingleDemo getInstance(){
return instance;
}
}
懒汉模式:
package lh.zjzk;
/**
* 饿汉模式
* @author Administrator
*
*/
public class SingleDemo2 {
private static SingleDemo2 instance = null;
private SingleDemo2(){}
public static SingleDemo2 getInstance(){
if(instance == null)
return new SingleDemo2();
return instance;
}
}
上面的代码猛一看,没有问题,但是仔细分析可以发现如果此单例被多线程访问,如果有1个线程在执行过if(instance == null),突然失去权,那么次线程就会暂停,如果线程2来访问,那么线程在此时判断instance==null为true,就会生成一个全新的实例,当线程1再一次获取权时,因为线程1已经判断并且符合条件,,那么线程1也会产生一个实例,这就是说此单例产生了两个对象。
一般为了解决此问题,我们是synchronized关键字,使用线程同步技术来解决此问题。
package lh.zjzk;
/**
* 饿汉模式
* @author Administrator
*
*/
public class SingleDemo2 {
private static SingleDemo2 instance = null;
private SingleDemo2(){}
public static SingleDemo2 getInstance(){
synchronized (SingleDemo2.class) {
if(instance == null)
return new SingleDemo2();
return instance;
}
}
}
但是此方法解决在线程多时会出现效率问题
package lh.zjzk;
/**
* 饿汉模式
* @author Administrator
*
*/
public class SingleDemo2 {
private static SingleDemo2 instance = null;
private SingleDemo2(){}
public static SingleDemo2 getInstance(){
if(instance == null){
synchronized (SingleDemo2.class) {
if(instance == null)
return new SingleDemo2();
}
}
return instance;
}
}
上面程序使用2层判断,可以解决多线程的效率问题。