不要这样做。问题大于好处。
不管你是使用finalization、Reference API,还是a Cleaner
(基于Reference API),试图使用对象的生命周期来控制锁都会产生更多的问题。
无法保证对象会被垃圾回收。只要有足够的空闲堆内存,JVM 就没有理由让垃圾收集器运行。此外,即使垃圾收集器运行,也不能保证它会收集所有无法访问的对象。像 G1GC 这样的垃圾收集器专注于在给定的时间限制内尽可能多地回收内存,优先考虑对象年龄的影响。事实上,他们甚至不知道一个死物在周围躺了多久。
因此,当 JVM 对 GC 收集一堆较新的对象感到满意时,一个特定的无法访问的对象可能会无限期地保持未被收集。
更糟糕的是,对象有可能比预期更早地收集垃圾。对于显式锁定和解锁操作,这没有影响,因为程序的行为保持不变。但是,当您将对象的生命周期与解锁操作联系起来时,您就有麻烦了。这尤其适用于当对象仅服务于锁定和解锁动作并且解锁动作已被应用程序程序员忘记时,换句话说,锁定对象在执行锁定动作后完全未被使用。
为了防止提前收集,您需要类似的东西Reference.reachabilityFence(lockObject)
,但是当程序员忘记执行所需的解锁操作时,他们记住插入必要的可达性围栏的可能性有多大?他们更容易插入所需的解锁操作。
解决这个问题的任何尝试都远非简单,同时仍无法提供值得努力的保证。你最好强烈提醒你的锁类的用户需要解锁它。考虑在try-with-resource块中实施AutoCloseable
和宣传使用它。