1.设计模式——单例模式

八种单例模式对比

1.什么是单例模式?

单例模式就是让一个类在系统内存中只有一个实例对象,通常用一个静态方法提供。

2.为什么要用单例模式?

对于频繁创建和销毁的对象,以及创建重量级对象,耗时多的对象,都会增加内存开销,通过单例模式可以提高系统性能,节约内存资源。

3.八种设计模式对比

Method1:饿汉式(静态常量法)

public class Singleton{
	private Singleton() {}
	private static final Singleton s = new Singleton();
	public static Singleton getInstance() {
		return s;
	}
}

评论:该方式通过静态常量的方式提供实例,方法简洁,保证了线程安全,但是没有做到Lazy loading(懒加载),如果没有调用获取实例的方法,同时又加载了这个类(加载这个类的情况有很多),创建对象就造成了资源浪费,如果能确保一定用到这个实例,该方法推荐使用,JDK中Runtime类就是通过这种方法获取实例。

Method2:饿汉式(静态代码块)

public class Singleton{
	private Singleton() {}
	private static Singleton s;
	static{
	 	s = new Singleton();
	}
	public static Singleton getInstance() {
		return s;
	}
}

评论:该方法通过静态代码块的方法获得实例,静态代码块在类加载时执行,优缺点同Method1。

Method3:懒汉式-1

public class Singleton{
	private Singleton() {}
	private static Singleton s;
	public static Singleton getInstance() {
		if (s == null) {
			s = new Singleton();
		}
		return s;
	}
}

评论:该方式做到了懒加载,单线程使用没有问题;但是在多线程情况下,可能会创建多个实例,不能保证线程安全,不可用。

Method4:懒汉式-2

public class Singleton{
	private Singleton() {}
	private static Singleton s;
	public static synchronized Singleton getInstance() {
		if (s == null) {
			s = new Singleton();
		}
		return s;
	}
}

评论:该方式通过同步方法获取实例,保证了线程同步和懒加载,但是每次获取实例都要调用同步方法,造成效率低下,但从效率上不推荐使用。

Method5:懒汉式-3

public class Singleton{
	private Singleton() {}
	private static Singleton s;
	public static Singleton getInstance() {
		if (s == null) {
			synchronized (Singleton.class) {
				s = new Singleton();
			}
		}
		return s;
	}
}

评论:该方式通过同步代码块获取实例,保证了懒加载,但是不能保证线程同步,多线程情况下不可用。

Method6:双重检查

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

评论:该方式实例变量用volatile 修饰,在变化时立马同步到主内存,保证了线程同步、懒加载,也解决了效率问题,推荐使用。

Method7:静态内部类

public class Singleton{
	private Singleton() {}
	static class Single {
		private static final  Singleton s = new Singleton();
	}
	public static Singleton getInstance() {
		return Single.s;
	}
}

评论:该方式借助静态内部类的优势,加载Singleton的时候不加载Single ,保证了懒加载;Single类在使用的时候才加载,且只加载一次,保证了线程同步和效率问题,推荐使用。

Method8:枚举

enum Singleton{
	INSTANCE;
}

评论:该方式通过Singleton.INSTANCE得到实例,实例唯一,线程安全,推荐使用。

总结:

1.实现层面,以上八种方法在单线程下都是可行的;
2.多线程层面,Method3和Method5不可用;
3.效率层面,同步方法Method3不推荐;
4.懒加载层面,两种饿汉式Method1,2不推荐;
5.多方面考虑Method6,7,8推荐使用;
发布了28 篇原创文章 · 获赞 1 · 访问量 530

猜你喜欢

转载自blog.csdn.net/qq_40575302/article/details/104411094