什么是单例?
在整个系统当中只允许一个实例存在。
单例的实现:
(1)懒汉模式
/**
* 懒汉模式
* 高并发时会有多个实例
*/
public class Single1 {
//静态私有实例
private static Single1 single;
//静态构造
private Single1(){}
public static Single1 getInstance(){
if(single == null){
single = new Single1();
}
return single;
}
}
(2)饿汉模式
/**
*饿汉模式
*在没有使用此单例时,该单例就已加载在内存中
*/
public class Single2 {
//类加载时就实例化对象
private static final Single2 single = new Single2();
public static Single2 getInstance(){
//立即返回
return single;
}
}
(3)synchronized 同步方法
/**
*synchronized 同步方法式
*每次获取单例时,都要先获取锁,性能影响较大
*/
public class Single3 {
private static Single3 single;
private Single3(){}
public static synchronized Single3 getInstance(){
if(single == null){
single = new Single3();
}
return single;
}
}
(4)双重检验锁
/**
*双重检验锁
*每个线程最多只有在第一次的时候才会进入同步块
*/
public class Single4 {
private static volatile Single4 single;
private Single4(){}
public static synchronized Single4 getInstance(){
//多线程直接访问,不做控制吗,不影响性能
if(single == null){
synchronized (Single4.class) {
if(single == null){
single = new Single4();
}
}
}
//如果不为null,不会影响性能,只有第一次才会影响性能
return single;
}
}
(5)静态内部类
/**
*静态内部类
*/
public class Single5 {
private Single5(){}
public static synchronized Single5 getInstance(){
return InnerClass.single;
}
//只有用到内部的静态属性时才会加载到虚拟机中
private static class InnerClass{
private static Single5 single = new Single5();
}
}
(6)枚举
/**
*枚举
*/
public enum Single6 {
SINGLE_6;
public Single6 getInstance(){
return SINGLE_6;
}
}
单例的好处:
(1)对于频繁使用的对象,可以省略创建对象所花费的时间,这对于那些重量级对象而言,是非常可观的一笔系统开销;
(2)由于 new 操作的次数减少,因而对系统内存的使用频率也会降低,这将减轻 GC 压力,缩短 GC 停顿时间。