单例设计模式:确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例。
其通过private的构造函数确保之生成一个实例。
优点:
1.单例模式只有一个实例,减小了内存开销,如果一个对象需要频繁的创建销毁时优势很明显。
2.由于单例模式只有一个实例,所以减少了系统的性能开销。如果一个对象的创建需要依赖大量的资源,那么通过单例模式使其 长期驻留在内存空间是一个不错的选择。
3.单例模式可以避免对资源的多重占用,例如文件写入,由于只有一个实例存在则避免了对同一个文件的同时写入。
4.单例模式可以在系统设置全局的访问点,优化和共享资源访问。
缺点:
1.单例模式没有接口扩展很难,如果想要扩展就只能修改代码了。
Tips: Q:单例模式为什么不能增加接口呢?
A:因为接口对单例模式是没有任何意义的,单例模式要求自行实例化,并且提供单一实例,接口和抽象类是不能被实例化的。
2.单例模式是对测试不利的。
3.单例模式与单一职责原则有冲突。
使用场景:
在一个系统中要求一个类只有一个对象,如果出现多个则会出现一些奇奇怪怪得事情,这时候就可以使用单例模式。
1.在一个项目中需要一个共享访问节点或共享数据。例如:Web计数器。
2.创建一个对象需要消耗的资源过多。
3.需要生成唯一东西的地方。
4.需要大量的定义静态常量,静态方法,比如工具类,当然也是可以使用static的。
通用类图:
单例模式难点就是高并发情况下的线程同步问题。
常见写法:
1.饿汉式
public class Singleton {
private static Singleton
instance =
new Singleton()
;
private
Singleton() {
}
public static Singleton
newInstance() {
return
instance
;
}
}
2.饿汉式(静态代码块)
public class Singleton {
private static Singleton
instance
;
static {
instance =
new Singleton()
;
}
private
Singleton() {
}
public static Singleton
newInstance() {
return
instance
;
}
}
3.懒汉式(非线程安全)
public class Singleton {
private static Singleton
instance
;
private
Singleton() {
}
public static Singleton
newInstance() {
if (
instance ==
null) {
instance =
new Singleton()
;
}
return
instance
;
}
}
4.懒汉式(synchronized)线程安全
缺点:每次调用都会被锁所困扰,即使只有第一次调用需要同步。
public class Singleton {
private static Singleton
instance
;
private
Singleton() {
}
public static synchronized Singleton
newInstance() {
if (
instance ==
null) {
instance =
new Singleton()
;
}
return
instance
;
}
}
5.懒汉式(双重检测锁定)
public class Singleton {
private static Singleton
instance
;
private
Singleton() {
}
public static Singleton
newInstance() {
if (
instance ==
null) {
synchronized (Singleton.
class) {
if (
instance ==
null) {
instance =
new Singleton()
;
}
}
}
return
instance
;
}
}
6.枚举
public enum Singleton {
INSTANCE
;
public void
doSomething() {
}
}
7.静态内部类
public class Singleton {
private
Singleton() {
}
public static class InnerSingleton {
private static final Singleton
instance =
new Singleton()
;
}
public static Singleton
newInstance() {
return InnerSingleton.
instance
;
}
}
Q:单例模式在多进程中如何保证只有一个实例的?
A:期待…。