单例设计模式
2022/3/31 23:19:31
本文主要是介绍单例设计模式,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
单例设计模式
比较常见的有spring提供的ioc,控制翻转,只需要加一个componet注解,默认注解修饰的对象就是单例的
如果自己要实现一个单例,应该是如何一个思路呢
借鉴xxl-job里面客户端的代码
功能:一个线程后台起,每隔1天去扫描一下日志文件,只保留最近的30个日志文件的功能
代码样例
public class JobLogFileCleanThread { private static Logger logger = LoggerFactory.getLogger(JobLogFileCleanThread.class); private static JobLogFileCleanThread instance = new JobLogFileCleanThread(); public static JobLogFileCleanThread getInstance(){ return instance; } private Thread localThread; private volatile boolean toStop = false; public void start(final long logRetentionDays){ // limit min value if (logRetentionDays < 3 ) { return; } localThread = new Thread(new Runnable() { @Override public void run() { while (!toStop) { try { // clean log dir, over logRetentionDays File[] childDirs = new File(XxlJobFileAppender.getLogPath()).listFiles(); if (childDirs!=null && childDirs.length>0) { // today Calendar todayCal = Calendar.getInstance(); todayCal.set(Calendar.HOUR_OF_DAY,0); todayCal.set(Calendar.MINUTE,0); todayCal.set(Calendar.SECOND,0); todayCal.set(Calendar.MILLISECOND,0); Date todayDate = todayCal.getTime(); for (File childFile: childDirs) { // valid if (!childFile.isDirectory()) { continue; } if (childFile.getName().indexOf("-") == -1) { continue; } // file create date Date logFileCreateDate = null; try { SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd"); logFileCreateDate = simpleDateFormat.parse(childFile.getName()); } catch (ParseException e) { logger.error(e.getMessage(), e); } if (logFileCreateDate == null) { continue; } if ((todayDate.getTime()-logFileCreateDate.getTime()) >= logRetentionDays * (24 * 60 * 60 * 1000) ) { FileUtil.deleteRecursively(childFile); } } } } catch (Exception e) { if (!toStop) { logger.error(e.getMessage(), e); } } try { TimeUnit.DAYS.sleep(1); } catch (InterruptedException e) { if (!toStop) { logger.error(e.getMessage(), e); } } } logger.info(">>>>>>>>>>> xxl-job, executor JobLogFileCleanThread thread destory."); } }); localThread.setDaemon(true); localThread.setName("xxl-job, executor JobLogFileCleanThread"); localThread.start(); } public void toStop() { toStop = true; if (localThread == null) { return; } // interrupt and wait localThread.interrupt(); try { localThread.join(); } catch (InterruptedException e) { logger.error(e.getMessage(), e); } } }
代码分析
- JobLogFileCleanThread 类就是一个单例模式,内部有一个静态变量instance,默认值是new JobLogFileCleanThread()自己本身
- 静态方法getInstance()取到的变量就是静态变量instance
- 为什么这个JobLogFileCleanThread的线程类自己本身没有继承Thread父类呢,而是里面又内嵌了一个Thread类型的localThread变量?
- JobLogFileCleanThread 自己有一个start方法,且是可以传递参数的,默认线程类Thread的start是不可以接受参数的,所以JobLogFileCleanThread类自己本身没有继承Thread类
- 可以看出start(long logRetentionDays)方法,内部起了一个new Thread的匿名内部类,并赋值给了变量localThread,匿名内部类里面写自己的业务逻辑,并且是个死循环,依赖一个flag标记,这个flag标记由voliate修饰,杜绝线程之间可见性问题也可以做到执行方法stop的时候,可以优雅关闭死循环的线程。
这篇关于单例设计模式的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-27消息中间件底层原理资料详解
- 2024-11-27RocketMQ底层原理资料详解:新手入门教程
- 2024-11-27MQ底层原理资料详解:新手入门教程
- 2024-11-27MQ项目开发资料入门教程
- 2024-11-27RocketMQ源码资料详解:新手入门教程
- 2024-11-27本地多文件上传简易教程
- 2024-11-26消息中间件源码剖析教程
- 2024-11-26JAVA语音识别项目资料的收集与应用
- 2024-11-26Java语音识别项目资料:入门级教程与实战指南
- 2024-11-26SpringAI:Java 开发的智能新利器