首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java终结器的替代方案

Java终结器的替代方案
EN

Stack Overflow用户
提问于 2020-06-30 06:57:08
回答 1查看 200关注 0票数 2

我正在使用Mysql GET_LOCK在分布式系统中实现一个锁定服务。在调用我的getLock()方法时,如果客户端获得了锁,我在DB中创建一个条目,并在锁释放时删除该条目。

假设调用客户端会在达到其目的后释放锁。但是,我希望确保锁被释放,以防客户端不释放它或没有进行适当的清理。

一种方法是在调用finalize时在我的锁对象上使用finalize方法来释放它。然而,它并不理想,增加了复杂性,在Java 9中被弃用。我读到过关于幻影引用的文章,它比终结器更好,但它的复杂程度也很高。我把它作为我最后的手段。

有没有更简单,更少依赖JVM的方法来处理这个用例?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-06-30 16:10:50

不要这样做。问题大于好处。

无论您使用的是finalization、Reference API还是Cleaner (依赖Reference API),尝试使用对象的生命周期来控制锁都会产生更多的问题。

不能保证某个对象会被垃圾回收。只要有足够的空闲堆内存,JVM就没有理由让垃圾收集器运行。此外,即使垃圾收集器运行,也不能保证它将收集所有无法访问的对象。像G1GC这样的垃圾收集器专注于在给定的时间限制内回收尽可能多的内存,优先考虑效果而不是对象年龄。事实上,他们甚至不知道一个死亡的物体会躺在那里多长时间。

因此,当JVM很高兴GC收集了一堆新的对象时,某个特定的无法到达的对象可能会无限期地不被收集。

更糟糕的是,对象有可能被get garbage collected earlier than expected。对于显式的锁定和解锁操作,这没有任何影响,因为程序的行为保持不变。但是,当您将对象的生命周期与解锁操作相关联时,you’re in trouble。这尤其适用于当对象仅服务于锁定和解锁动作并且解锁动作已被应用程序员遗忘时,换句话说,锁定对象在执行锁定动作之后完全未被使用。

为了防止早期收集,您需要像Reference.reachabilityFence(lockObject)这样的东西,但是当程序员忘记执行所需的解锁操作时,他们记着插入必要的可达性围栏的可能性有多大?对于他们来说,插入所需的解锁操作会更容易。

任何试图解决这个问题的尝试都将远远不是简单的,同时仍然不能提供值得努力的保证。你最好提醒你的锁类的用户需要解锁它。考虑实现AutoCloseable并在try-with-resource块中使用它进行通告。

票数 7
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/62647855

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档