首先是饿汉式:
public class Singleton {
private static Singleton s = new Singleton();
//屏蔽外部的new
private Singleton() {
super();
}
//提供一个全局的访问点
public static Singleton getInstance() {
return s;
}
public void A(){
System.out.println("xixi");
}
}
public class SingletonTest {
public static void main(String[] args) {
// TODO Auto-generated method stub/* Singleton s1 = Singleton.s;
Singleton s2 = Singleton.s;*/
Singleton s1 = Singleton.getInstance();
Singleton s2 = Singleton.getInstance();
System.out.println(s1 .equals(s2)); //true
s1.A();
}
对于懒汉式,在类加载的过程中就会去创建这个类的实例,并没有达到延迟加载的效果,但是线程是安全的!
然后是懒汉式:跟饿汉式的区别就是没有在一开始就初始化了,
//会在这个方法里面初始化
public synchronized static Singleton getInstance() {
if(s==null) {
s = new Singleton();
}
return s;
}
注意:没有加锁的懒汉式是线程不安全的,但是如果加了锁之后,每个线程执行该方法的时候都会进行线程等待,就会导致同步情况下执行效率低!
所以只需要判断第一次是否为空的时候需要加锁,其余时候是不需要加锁的,为了解决这个问题,就有了双重验证式!
public static Singleton getInstance() {
if(s==null) {
synchronized(Singleton.class) {
if(s== null) {
s=new Singleton();
}
}
s = new Singleton();
}
return s;
}
注:双重验证式具有延迟加载,线程安全,同步情况效率高,唯一就是实现相对复杂!
对于类加载方式,具有以上所有的优点,并且实现简单
public class Singleton {
//屏蔽外部的new
private Singleton() {
}
//静态内部类,用于创建唯一的Singleton的实例
private static class OnlyInstanceHolder{
static private Singleton Only = new Singleton();
}
//公开的唯一访问点
public static Singleton getInstance() {
return OnlyInstanceHolder.Only;
}
唯一的缺陷是不能防止反序列化!