单例目前有6中实现方式
1、饿汉式
/**
* 饿汉式
* 随着类加载便初始化了,基于类加载器,避免的多线程问题,如果不使用这个类会造成资源浪费,占用内存
*/
public class SingletonHungry {
private static SingletonHungry instacne = new SingletonHungry();
private SingletonHungry(){
}
public static SingletonHungry getInstacne() {
return instacne;
}
}
2、懒汉式
/**
* 懒汉式
*
* 用户第一次调用初始化,节约资源,不用不初始化,在多线程模式下失效
*
*
*/
public class SingletonLazy {
private static SingletonLazy instacne;
private SingletonLazy(){
}
public static SingletonLazy getInstacne() {
if(instacne == null) {
instacne = new SingletonLazy();
}
return instacne;
}
}
3、懒汉式,获取方法加同步锁
/**
* 懒汉式,获取方法加同步锁
*
* 为了解决多线程并发问题,这里在获取单例方法前加上了同步,这样在每次获取的时候都需要进行同步,在高并发下这种开销是巨大的
* 而且大多数情况下我们并不会用到同步,量级太重,因此这种方式基本不建议使用
*
*
*/
public class SingletonLazySyn {
private static SingletonLazySyn instacne;
private SingletonLazySyn(){
}
public static synchronized SingletonLazySyn getInstacne() {
if(instacne == null) {
instacne = new SingletonLazySyn();
}
return instacne;
}
}
4、懒汉式,双检查模式
/**
* 懒汉式,双检查模式
*
* 双重检查,第一次空是为了解决不必要的同步问题,只有在实例为空的情况下才回去检查,第二次判空是为了实例为空时才创建实例
*
* volatile修饰的变量在使用时都会先刷新,也就是将其他线程的工作内存中的数据先同步回主内存,对于执行引擎看不到不一致
* 情况,所以对于多线程来说,不存在不一致问题,是一种轻量级的同步机制
* volatile可以防止指令重排序优化
*
* volatile变量的运算在并发下并一样不安全
*
*/
public class SingletonLazyDCL {
private static volatile SingletonLazyDCL instacne;
private SingletonLazyDCL(){
}
public static SingletonLazyDCL getInstacne() {
if(instacne == null) {
synchronized(SingletonLazyDCL.class) {
if(instacne == null) {
instacne = new SingletonLazyDCL();
}
}
}
return instacne;
}
}
5、静态内部类实现单例
/**
* 静态内部类实现单例
* 静态内部类实现单例模式,第一次SingletonStaticInner被加载的时候不会初始化sInstance,只有当getInstance第一次
* 被调用的时候java虚拟机才会加载SingletonHolder
*
* 一个内部类并不会在其外部类被虚拟机加载的时候被同时加载
* 这种方式保证了懒加载的特性,又保证了多线程并发的问题
*/
public class SingletonStaticInner {
private SingletonStaticInner(){
}
public static SingletonStaticInner getInstance() {
return SingletonHolder.sInstance;
}
private static class SingletonHolder {
private static final SingletonStaticInner sInstance = new SingletonStaticInner();
}
}
6、枚举单例
/**
* 枚举单例
*
* 默认枚举的实例创建是线程安全的,并且在任何情况下都是单例。
*/
public enum SingletonEnum {
INSTANCE;
public void doSomeThing() {
}
}