4 回答
TA贡献1829条经验 获得超9个赞
还是这段代码会保证执行过程永远不会在处理单个文件时尝试中途关闭?
此代码保证此处启动的关闭不会在处理单个文件的过程中发生。也许很明显,您代码中的其他地方可以调用System.exit
,而您对此没有任何保护。
您可能需要考虑防止System.exit
被调用,然后让您的代码正常关闭(即通过方法的正常完成main
)。
TA贡献1780条经验 获得超5个赞
万一你真的有多个线程调用不同的方法,synchronized这样使用实际上是一个聪明的主意,因为它处理了“多线程”的事情。
您可以考虑缩小第一个块的范围:
Path currentFileName = getNextFile();
String string = readFile(currentFileName);
synchronized(monitor) {
单独读取文件应该不是问题。(当然,除非您此处的代码必须保证由 返回的 PathgetNextFile()得到完全处理)。
TA贡献1744条经验 获得超4个赞
如果代码在synchronized
块中执行并且块在同一个对象上同步,并且synchronized
循环中块中调用的方法while
完全在与其调用者相同的线程上运行,则不存在文件相关进程被中断的风险通过调用System.exit
. _
这就是说,它看起来确实像是一个有争议的补丁,只是稍微改进了有争议的代码。
可能还存在更具体的饥饿风险,因为显示的 while 循环似乎尽可能快地向这些文件操作发送垃圾邮件,因此在退出时尝试获取锁可能不会成功。
探索的一般方向是将无限while
循环转换为ScheduledExecutorService
+ Runnable
,使用自己的监视器执行每 x 时间量以防止对相同文件的重叠操作,并在shutdown
调用该方法时优雅地终止它。
TA贡献1775条经验 获得超11个赞
您可以使用关闭挂钩。来自 javadocs:
关闭挂钩只是一个已初始化但未启动的线程。当虚拟机开始其关闭序列时,它将以某种未指定的顺序启动所有已注册的关闭挂钩,并让它们同时运行。
由此,您可以从您的文件类中提供一个关闭挂钩,如下所示:
public Thread getShutdownHook() {
return new Thread(() -> {
synchronized (monitor) {
// gracefully handle the file object
}
});
}
这将在调用时调用Runtime.getRuntime().exit()(由 调用System.exit())。由于它也在监视器对象上同步,如果其他线程正在使用该文件,关闭挂钩将阻塞直到它空闲为止。
添加回答
举报