繁体   English   中英

如何安全,及时地用Java处理稀缺的共享资源?

[英]How can I safely and timely dispose a scarce shared resouce in Java?

在并行应用程序中,线程组中的线程(32)使用共享的非托管和独立的一次性对象。

我们的c / c ++应用程序具有相同的功能,在这里我使用了shared_ptr<>以便让对象在不需要对象后立即进行处理和完成。

我只是试图在Java中应用相同的东西,而我遇到了finalize()方法。 但是存在一些问题,因为有时GC是如此的懒惰,所以甚至没有将对象标识为无法处置/完成的对象,有时将其称为,但是没有保证GC可以让该对象完全调用finalize()

因此,我想到了另一个复杂的解决方案,我只是递减计数并跟踪线程是否也无法使用该对象,但是我知道这不是一个可靠的解决方案,而且我知道我将面对意外的结果。

我只是想知道Java中是否有与shared_ptr<>等效的东西,还是可以通过JNI处理对象?

有任何想法吗?

做好自己想要的事情需要付出一些努力,并且在Java中永远不会感觉很自然,因为确定性的资源清理对于Java来说陌生的。 自Java 7以来,它已经变得更好了。

解决此问题的最佳方法是:

  1. 将类型为java.util.concurrent.AtomicInteger的计数器添加到Java包装器中,该计数器初始化为1( 为此 ,感谢@Jules ,现在避免了synchronized !)。
  2. 添加addRef方法,它抛出,如果计数器为0,返回this为更好地利用try语句来。
  3. 实现java.lang.AutoCloseableclose不为0时减少计数,而当计数为0时释放资源。
  4. 添加终结器作为最终的安全网:记录失败以更早地正确释放资源并进行最终释放。
  5. 向拥有此类引用且不是try-with-resource的每个变量/参数添加注释,因此您知道调用addRef并适当close

使用Java包装器的try-with-resources -block:

try(resource.AddRef()) {
    // Do your thing
}

tldr; 在Java中,没有强制“破坏”对象的通用方法- 在收集到对象时调用finalize方法 (这可能永远不会!)

通常唯一需要担心的资源外部资源,例如文件或流-处理这种情况的通用方法是通过close/AutoClosable使用手动生存期管理(对于终结器,如果使用,则只是 “安全”) )。 生存期完全留在调用方中,并且过早“关闭”资源(例如文件)将使其在其他地方无效。

可以使用获取/释放池来完成此手动管理(当所有获取都被释放时,“使用计数”变为零,并在基础资源上调用close ); 如果可以预先固定计数,则表示信号量有变化。

另一方面,内部管理但不再可访问的对象/资源将根据GC的需要逐出,因此(通常)无需担心它们的寿命。

取决于您如何看待它。

Java中没有诸如shared_ptr之类的东西,因为Java中没有诸如value对象之类的东西(除了像int这样的原始类型),而且RAII不存在。

或者... Java中的所有内容都与shared_ptr一样,因为所有内容都是共享引用,其行为更像是引用计数的指针。

Java中的等效项只是普通的对象引用。 让GC进行工作。 您应该几乎永远不要使用finalize

一种替代方法是使用PhantomReference这使您可以设置一些处理,以在停止引用该对象之后的某个时候进行。

当您的对象被停止引用时,需要采取一些措施的原因是什么?

没有这样的事情-在Java中使用完指针或空闲对象后,就不会再使用它们了。 好吧,您可以这样做,但是机会是-您做错了。

如果在所有线程处理完对象后必须执行某项操作,则应自己跟踪其使用情况,并在完成后进行清理。

您可以创建一个简单的管理器对象,该对象知道如何创建和处置相关资源。 您在对象上实现了同步的checkout()checkin()方法。 checkout方法将在第一次调用时创建对象,增加引用计数,然后返回对该对象的引用。 checkin方法递减引用计数,当它变为零时,它将处置该对象。 那么您只需使用try / finally模式(类似于锁定/解锁)来限制对象的所有用法:

Resource res = manager.checkout();
try {
  // ... work with resource here ...
} finally {
  manager.checkin(res);
}

注意,您可以使用java 7 AutoCloseable使它更加简洁。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM