单例模式

饿汉式

静态变量方式

public class Singleton1 {

	private final static Singleton1 instance=new Singleton1();
	
	private Singleton1() {}
	
	public static Singleton1 getInstance() {
		return instance;
	}
}

静态代码块方式

public class Singleton2 {

	private static Singleton2 instance;
	
	static {
		instance=new Singleton2();
	}
	
	private Singleton2() {}
	
	public static Singleton2 getInstance() {
		return instance;
	}
}

懒汉式

线程不安全式

public class Singleton3 {

	private static Singleton3 instance;
	
	private Singleton3() {}
	
	public static Singleton3 getInstance() {
		if(instance==null) {
			instance=new Singleton3();
		}
		return instance;
	}
}

线程安全式

public class Singleton4 {

	private static Singleton4 instance;
	
	private Singleton4() {}
	
	public synchronized static Singleton4 getInstance() {
		if(instance==null) {
			instance=new Singleton4();
		}
		return instance;
	}
}

双重检查方式

public class Singleton5 {

	private static volatile Singleton5 instance;
	
	private Singleton5() {}
	
	public static Singleton5 getInstance() {
		if(instance==null) {
			synchronized (Singleton5.class) {
				if(instance==null) {
					instance=new Singleton5();
				}
			}
		}
		return instance;
	}
}

为什么需要双重检查?

加入有两个线程A、B都执行到了if(instance==null)这个语句,而A线程先拿到了锁,生成了对象,如果A线程是否了锁,B线程此时拿到锁,如果不在执行一次判断if(instance==null)的话,那么就又会生成一个实例,那么就不是严格的单例模式

静态内部类方式

public class Singleton6 {

	private static class SingletonInstance{
		private static final Singleton6 INSTANCE=new Singleton6();
	}
	
	private Singleton6() {}
	
	public static Singleton6 getInstance() {
		return SingletonInstance.INSTANCE;
	}
}

外部类的加载不会导致内部类的加载,只有当内部类别使用时才会导致加载,并且类加载的时候JVM保证线程安全,所以利用这种方式即能保证线程安全又能保证懒加载

枚举方式

public enum Singleton7 {
	INSTANCE;
	
	public void method() {
		System.out.println("method");
	}
}

利用枚举的特性,得到的实例都是单例的。

原文地址:https://www.cnblogs.com/moyuduo/p/13047910.html