怎么简单的锁定文件夹

今天,我们将讨论使事情保持简单,愚蠢(KISS)和鲁棒性的设计价值之间,设计不足和过度设计之间的冲突。

我们正在编写一个批处理Java应用程序,需要确保在服务器上一次最多运行一个实例。 团队成员有一个很好的想法,那就是使用锁定文件,这确实有效并且对我们有很大帮助。 但是,最初的实现不是很健壮,由于对该死的应用程序拒绝运行和查找锁定文件进行故障排除,这使我们花费了宝贵的时间和昂贵的上下文切换。

正如Comoyo的ØyvindBakksjø最近解释的那样,软件工程师与纯粹的编码器的不同之处在于,不仅要思考和关心通过代码的快乐路径,而且还要考虑不快乐的情况。 优秀的工程师会考虑可能出现的问题,并尝试适当地处理它们,以便依赖于它们和其用户的代码可以更轻松地处理有问题的情况。 健壮性包括及早发现错误,以良好的方式处理错误以及提供有用和有用的错误消息。 另一方面,简单性[TBD:Hickey]是系统的关键特征。 花太多时间来制作防弹代码总是很容易,而不是将精力集中在对业务更有价值的地方。

过于简单的实现

最初的实现非常简单:

public class SimpleSingletonBatchJob {private static boolean getLock() {File file = new File(LOCK_DIRECTORY+File.separatorChar+Configuration.getGroupPrefix());try {return file.createNewFile();} catch (IOException e) {return false;}}private static void releaseLock() {File file = new File(LOCK_DIRECTORY+File.separatorChar+Configuration.getGroupPrefix());file.delete();}public static void exit(int nr) {releaseLock();System.exit(nr);}public static void main(String[] args) throws IOException {...if (! getLock()) { // #1 try to create lockSystem.out.println("Already running");return;}... // do the job (may throw exceptions)releaseLock(); // #2 release lock when done}
}

主要问题是,如果该应用程序失败或被终止,它将留下锁定文件,而下次它将拒绝并以无用的错误消息开头。 您将需要了解/阅读代码以了解如何解决问题。

有人认为,这样的失败和故意的失败只会很少发生,以致于使代码更健壮的努力是没有道理的。 但是,我们需要投入很少的精力来使代码更加友好和健壮,f.ex。 通过在错误消息中包括锁定文件路径并解释为什么可能存在锁定文件路径以及如何解决该问题(例如“如果应用未运行,则锁定是失败运行的残余,可能会被删除”)。 确保在失败时删除文件是一些琐碎的代码行,可以节省一些混乱和时间。 另外,值得一提的是使其更强大,从而不需要太多的人工干预–对您的操作人员很友好。 (我希望是你。)

更强大的实施

这是改进的版本,具有有用的错误消息,并在失败时删除锁:

public class RobustSingletonBatchJob {// Note: We could use File.deleteOnExit() but the docs says it is not 100% reliable and recommends to// use java.nio.channels.FileLock; however this code works well enough for usstatic synchronized boolean getLock() {File file = new File(LOCK_DIRECTORY, StaticConfiguration.getGroupPrefix());try {// Will try to create path to lockfile if it does not exist.file.getParentFile().mkdirs(); // #1 Create the lock dir if it doesn't existif (file.createNewFile()) {return true;} else {log.info("Lock file " + file.getAbsolutePath() + " already exists."); // #2 Helpful error msg w/ pathreturn false;}} catch (IOException e) {throw new RuntimeException("Failed to create lock file " + file.getAbsolutePath()+ " due to " + e + ". Fix the problem and retry.", e); // #3 Helpful error message with context (file path)}}private synchronized static void releaseLock() {File file = new File(LOCK_DIRECTORY, StaticConfiguration.getGroupPrefix());file.delete();}public static void main(String[] args) throws Exception {boolean releaseLockUponCompletion = true;try {...if (! getLock() {releaseLockUponCompletion = false;log.error("Lock file is present, exiting."); // Lock path already loggedthrow new RuntimeException("Lock file is present"); // throwing is nicer than System.exit/return}... // do the job (may throw exceptions)} finally {if (releaseLockUponCompletion) {releaseLock(); // #4 Always release the lock, even upon exceptions}}
}

改进之处:

  1. 如果不存在锁,则创建一个存储锁的目录(该锁不存在,并导致令人困惑的“已运行”错误消息)已经使我们感到痛苦
  2. 有用的错误消息“锁定文件<文件的绝对路径>已存在。” =>易于复制和粘贴int rm
  3. 有用的错误消息,其中包含文件路径和错误信息,当我们无法创建锁时(空间不足,目录权限不足等)。
  4. 将整个主程序包装起来进行尝试–最后,确保始终删除锁定文件

代码仍然不是完美的-如果您终止了该应用程序,则锁定文件仍将留下。 有多种方法可以解决该问题(例如,将应用程序的pid包含在文件中,在启动时不仅检查其是否存在,而且还应检查pid确实存在/是否为该应用程序),但是在处理时间方面和增加成本方面复杂性的确高于收益。

结论

KISS和鲁棒性都是重要目标,并且经常会发生冲突。 使您的代码变得比所需的更健壮会使其变得过于复杂,并浪费时间,并且机会成本(丢失)。 由于故障排除,使代码过于简单会花费您或它的用户大量时间。 要实现正确的平衡,需要经验并不断地寻求平衡。 如果您的团队无法达成共识,最好从一个简单的代码开始,并根据其实际的健壮性需求收集硬数据,而不是事先对其进行过度设计。 不要像我一样成为完美主义者,但也要对您的用户和开发者同好。 如果您可以毫不费力地使您的应用程序更强大,那就去做吧。 如果需要更多工作,请去收集数据以证明(或不需要)该工作。

参考: 简单性与鲁棒性–在Wonders of Code博客上由我们的JCG合作伙伴 Jakub Holy 演示了锁定文件处理 。

翻译自: https://www.javacodegeeks.com/2013/09/simplicity-vs-robustness-demonstrated-on-lock-file-handling.html

怎么简单的锁定文件夹

怎么简单的锁定文件夹_简单性与鲁棒性–在锁定文件处理中展示相关推荐

  1. 简单性与鲁棒性–在锁定文件处理中展示

    今天,我们将讨论在设计不足和过度设计之间保持简单,愚蠢(KISS)和鲁棒性的设计价值之间的冲突. 我们正在编写一个批处理Java应用程序,需要确保在服务器上一次最多运行一个实例. 一个团队成员有一个很 ...

  2. putty怎么进入文件夹_如何利用putty工具上传文件 - 卡饭网

    图解使用FTP工具上传文件以FlashFXP为例 图解使用FTP工具上传文件以FlashFXP为例 现以FlashFXP为例,图解使用FTP工具上传文件. 1: 运行 LeapFTP,点击1处(站点- ...

  3. mcldownload文件夹_我的世界存档在哪个文件夹及导入存档的方法介绍

    现在很多游戏都有存档功能,我的世界也不例外,有些玩家想知道我的世界存档在哪个文件夹,今天就让小编告诉大家我的世界电脑存档位置吧. 我的世界存档在哪个文件夹 电脑版我的世界: 在我的电脑里找我的世界的根 ...

  4. 启用tim无法访问文件夹_如何在三星手机上启用安全文件夹

    启用tim无法访问文件夹 The Secure Folder is a useful feature on Samsung devices that allows you to keep apps a ...

  5. python如何生成excel文件夹_用python脚本通过excel生成文件夹树结构

    大概这样写标题是对的吧... 目标: 通过excel目录结构文档生成文件夹树结构. 也就是: 通过下面的excel 生成下面的文档树结构: 方法: 1.分析:一般文档结构都是事先构思好.可以在txt文 ...

  6. python找不到scripts文件夹_快速解决安装python没有scripts文件夹的问题

    安装Python2.7,好多次都不会产生scripts文件夹,导致无法使用pip. 折腾了一下,找到了解决办法. 让人无法接受的是,只要是我给的安装包一定不会产生scripts文件夹,所以应该是我的安 ...

  7. java scp 文件夹_利用scp 远程上传下载文件/文件夹

    scp是secure copy的简写,用于在Linux下进行远程拷贝文件的命令,和它类似的命令有cp,不过cp只是在本机进行拷贝不能跨服务器,而且scp传输是加密的.可能会稍微影响一下速度.当你服务器 ...

  8. ubuntu复制文件到另一个文件夹_简单介绍一下电脑中的文件或文件夹的复制、移动及删除的操作方式...

    大家好,我是波仔,今天又来跟各位学电脑基础的朋友们分享知识,让我们一起来学习吧. 复制文件或文件夹 在我们日常操作文件或文件夹的过程中,经常会遇到需要复制一些文件或文件夹什么的,下面我们就一起来分享一 ...

  9. 电脑字体在哪个文件夹_电脑键盘使用方法

    对于刚使用电脑的电脑新手而言,首先要做的就是熟悉键盘.不过,小编发现有许多的童鞋都怕文字过于繁多看的自己眼花,别担心,小编这有电脑键盘的示意图,能让大家一目了然. 对于经常需要使用电脑的人而言,键盘那 ...

最新文章

  1. 软考总结——虚存管理
  2. 商品秒杀,防并发解决思路
  3. html5引入spring标签,[MVC]5 使用Spring标签库
  4. 与视频服务器相比,流媒体服务器有什么优势?
  5. 【原创】user.id字段
  6. php 代码线程,php实现多线程代码
  7. xpath+多进程爬取网易云音乐热歌榜。
  8. Spring Boot jackson配置使用详解
  9. java获取C盘下的隐藏目录文件名称
  10. c语言的跳线帽,电脑主板上跳线帽有什么作用图文介绍
  11. perl语言中的AWK之基础篇
  12. python游戏设计教程视频_零基础python教程-用Python设计你的第一个小游戏
  13. 理解SimpleExpandableListAdapter的构造函数
  14. 1. DFT 入门篇-scan chain
  15. wireless-tools源码分析-iwlist
  16. 初中英语和计算机融合的教学案例,信息技术与初中英语学科教学的深度融合
  17. 芯片数据手册阅读方法
  18. 网易云信短信功能使用
  19. Java随机生成4位随机数字+字母
  20. css的`class`选择器选择前缀.

热门文章

  1. 初一模拟赛总结(5.11)
  2. Sentinel(十九)之主流框架的适配
  3. Spring Boot之基于Redis实现MyBatis查询缓存解决方案
  4. Spark入门(一)单主standalone安装
  5. javafx爬取网页并且初始化网页数据
  6. 一文带你理解Java中Lock的实现原理
  7. Oracle入门(十四.21)之创建DML触发器:第二部分
  8. 【JDBC】Eclipse连接Mysql
  9. 有一种陪伴不在身边,却在心间
  10. MyBatis中的原理