Java 单例模式 (Singleton Pattern)
2019-12-27 本文已影响0人
Mrs_MR
分享两个典型的Java单例模式写法:
第一种: 双检锁机制实现单例模式 -- 较复杂,且无法避免使用反射和反序列化的方式来获得该实例;
第二种: 使用枚举来实现单例模式 -- 代码简单, 可以解决反射/反序列化获取实例的问题, 另外其本身也是线程安全的;
第一种方式代码:
/**
*
* 单例模式:Singleton Pattern
* 主要解决:一个全局使用的类频繁地创建与销毁。
* 何时使用:当您想控制实例数目,节省系统资源的时候。
* 如何解决:判断系统是否已经有这个单例,如果有则返回,如果没有则创建。
* 关键代码:构造函数是私有的。
*
* 本例使用:
* 双检锁/双重校验锁(DCL, 即 double-checked locking)
*
* @author MY
* @date 2019/12/3
*/
public class SingleObject {
/**
* 创建实例
* 使用 volatile 关键字, 禁止重排序, 使所有的write操作都发生在read操作之前
* */
public static volatile SingleObject instance;
/** 将构造函数私有化 */
private SingleObject(){}
/** 获取实例 */
public static SingleObject getInstance(){
if(instance == null){
synchronized (SingleObject.class){
// 再次判空, 防止多个线程同时通过第一步判空操作
if(instance == null){
instance = new SingleObject();
}
}
}
return instance;
}
}
第二种方式代码:
/**
* 使用单元素枚举(enum)来实现单例模式
*
* @author MY
* @date 2019/12/30.
*/
public enum EnumSingleObject {
INSTANCE;
private Object instance;
EnumSingleObject(){
//todo: 在此处可以对instance做初始化操作
}
public EnumSingleObject getInstance(){
return INSTANCE;
}
}
第二种方法-实例:
import java.util.concurrent.*;
/**
* @author MY
* @date 2019/12/30.
*/
public class LocalThreadPoolExecutors {
enum EnumThreadPoolExecutor{
INSTANCE;
/** ThreadPoolExecutor */
private ThreadPoolExecutor threadPoolExecutor;
EnumThreadPoolExecutor(){
threadPoolExecutor = new ThreadPoolExecutor(5,
20 ,
10,
TimeUnit.SECONDS,
new LinkedBlockingQueue(128),
new ThreadPoolExecutor.CallerRunsPolicy()
);
}
/**
* @return
*/
public ThreadPoolExecutor getInstance(){
return threadPoolExecutor;
}
}
public static void main(String[] args){
EnumThreadPoolExecutor.INSTANCE.getInstance();
ThreadPoolExecutor threadPoolExecutor = EnumThreadPoolExecutor.INSTANCE.getInstance();
}
}