使用场景:一个类在程序中,只有一个实例。
如环境变量类,线程池,硬件设备,缓存等。在程序中有多个实例导致结果不一致,引发其他问题。
具体实现:
1.构造方法私有化。封闭初始化方法。
2.提供静态方法获取对象。提供方法,获取对象实例。
3.声明静态变量作为自己的属性。全局的静态唯一对象。
懒汉式:使用时才创建,不被使用永远不会被创建实例。
优点:节省内存。
缺点:线程不安全
代码:
public class SingleClass {
private static SingleClass singleClass;
// 构造方法私有化
private SingleClass(){
}
public static SingleClass getInstance(){
if(null == singleClass){
singleClass=new SingleClass();
}
return singleClass;
}
}
饿汉式:初始化类就创建实例。
优点:线程安全
缺点:可能不调用就new 出了实例,占用内存。浪费资源。
代码:
public class SingleClass2 {
private static SingleClass2 singleClass2=new SingleClass2();
private SingleClass2(){}
public static SingleClass2 getInstance(){
if (null != singleClass2){
return singleClass2;
}else
{
return new SingleClass2();
}
}
}
解决懒汉模式多线程线程安全问题解决
在多线程的时候会有可能有多个线程调用getInstance方法,可能会有创建多个实例的情况。
这种情况下,简单的解决办法是给getInstance方法加同步锁
public class SingleClass {
private static SingleClass singleClass;
// 构造方法私有化
private SingleClass(){
}
public static synchronized SingleClass getInstance(){
if(null == singleClass){
singleClass=new SingleClass();
}
return singleClass;
}
}
但是有个问题,如果getInstance经常被调用,每次都要经过锁,消耗资源。
解决上面的情况可以使用双重检验方式。
public class SingleClass {
private static SingleClass singleClass;
// 构造方法私有化
private SingleClass(){
}
public static SingleClass getInstance(){
if(null == singleClass){
// 只会进一次同步锁方法块
synchronized (SingleClass.class){
if (null == singleClass){
singleClass=new SingleClass();
}
}
}
return singleClass;
}
}