单例模式的特点:
1.单例类只有一个实例
2.单例类必须自己创建自己的唯一实例
3.单例类必须给其他的对象提供这一实例
一:仅仅适用于单线程创建后返回
package test;
public class Test18 {
private static Test18 singleton=null;
private Test18 (){}
public static Test18 getInstance(){
if(singleton==null)
return new Test18();
else return singleton;
}
}
因为
多个线程同时第一次运行到如下语句if (instance == null){ …}此时多个线程的判断都为true,所以就都进行了一次实例化new Singleton ()。
优点:第一次调用才初始化,避免内存浪费。
缺点:必须加锁synchronized 才能保证单例,(如果两个线程同时调用getInstance方法,会chuxia)但加锁会影响效率。
对于这种情况给出了几种解决方案,逐渐变优。
方案零:静态构造函数,由于在C#中静态构造函数可以确保只调用一次,java中静态代码块有相同功能
package test;
public class Test18 {
private static Test18 singleton=null;
private Test18 (){}
static {
singleton=new Test18 ();
}
}
}
由于第一次加载类时就运行了所以太早的建立实例也会造成内存浪费。
方案一:加锁同一时刻只能一个线程能得到同步锁
package test;
public class Test18 {
static Object lock=new Object();
private static Test18 singleton=null;
private Test18 (){}
public static Test18 getInstance(){
synchronized (lock) {
if(singleton==null)
singleton=new Test18();
return singleton;
}
}
}
改良方案:两次判断singleton是否为空,如果第一次判断不为空就没必要进行加锁操作了
package test;
public class Test18 {
static Object lock=new Object();
private static Test18 singleton=null;
private Test18 (){}
public static Test18 getInstance(){
if(singleton==null){
synchronized (lock) {
if(singleton==null)
singleton=new Test18();
}
}
return singleton;
}
}
优点:第一次调用才初始化,避免内存浪费。
缺点:必须加锁synchronized 才能保证单例,(如果两个线程同时调用getInstance方法,会chuxia)但加锁会影响效率。
改良方案二:
package test;
public class Test18 {
static Object lock=new Object();
private static Test18 singleton=new Test18();
private Test18 (){}
public static Test18 getInstance(){
return singleton;
}
}
在类创建的同时就已经创建好一个静态的对象供系统使用,以后不再改变,所以天生是线程安全的。
优点:没有加锁,执行效率会提高。
缺点:类加载时就初始化,浪费内存。
原文来自:http://my.csdn.net/qq_35101189