单例模式
模式作用介绍
单例模式的特点:
1、单例类的实例化对象只有一个。
2、单例类必须自己创建自己的唯一实例。
3、单例类必须给其他类提供自己实例对象的方法。
4、单例类的构造方法必须是私有的
单例设计模式所解决的问题就是:保证类的对象在jvm实例内存中唯一。
1. 优点
提供了对唯一实例的受控访问。
由于在系统内存中只存在一个对象,因此可以节约系统资源,
对于一些需要频繁创建和销毁的对象单例模式无疑可以提高系统的性能。
可以根据实际情况需要,在单例模式的基础上扩展做出双例模式,多例模式。
2. 缺点
单例类的职责过重,里面的代码可能会过于复杂,在一定程度上违背了“单一职责原则”。
如果实例化的对象长时间不被利用,会被系统认为是垃圾而被回收,这将导致对象状态的丢失。
代码演示
单例实现-饿汉式
特点:线程安全,无法实现实例懒加载策略。
public class Single1 {
private static final Single1 s=new Single1();
private Single1(){}
public static Single1 getInstance(){
return s;
}
}
static 保证线程安全,在类的加载过程中,static关键字修饰的变量,会在链接的准备阶段进行分配内存和赋默认初始值,所以在使用阶段次对象实例已经存在,就不会导致线程不安全的问题。
单例模式-懒汉式
懒汉式和饿汉式相比的区别就是懒汉式创建了延迟对象,同时饿汉式的实例对象是被修饰为final类型。
优点:懒汉式的好处是显而易见的,因为是按需加载,只有需要的时候才去加载它的实例对象,尽最大可能节省了内存空间。
缺点:在多线程编程中,使用懒汉式可能会造成类的对象在内存中不唯一,
虽然通过修改代码可以改正这些问题,但是效率却又降低了。
特点:线程不安全,实现了实例懒加载策略。
public class Single2 {
private static Single2 s = null;
private Single2() { }
public static Single2 getInstance() {
if (s == null)
s = new Single2();
return s;
}
}
单例模式-全局锁式
特点:线程安全,且实现了懒加载策略,但是线程同步时效率不高。 需要用户和内核的交互
public class Single3 {
private static Single3 single3;
private Single3() {}
public synchronized static Single3 getInstance() {
if (single3 == null)
single3 = new Single3();
return single3;
}
}
synchronized 作用于static 方法 相当于锁住了类
作用于普通方法 相当于锁住了类的对象
作用于代码块 代码块 锁的是代码块
单例模式-静态内部类式
特点:线程安全,不存在线程同步问题,
且单例对象在程序第一次 getInstance() 时主动加载 SingletonHolder 和其 静态成员 INSTANCE,
因而实现了懒加载策略。
public class Single6 {
private Single6() {}
private static class SingletonHolder {
private static final Single6 INSTANCE = new Single6();
}
public static Single6 getInstance() {
return Single6.SingletonHolder.INSTANCE;
}
}