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

0 java multithreading garbage-collection object-lifetime

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

我们在c/c ++应用程序中有相同的东西,我shared_ptr<>在那里使用以便在不需要对象之后让对象进行处理和最终化.

我只是尝试在Java中应用相同的东西,我面对的finalize()方法.但是有一些问题,因为GC有时是如此懒惰,对象甚至没有被识别为处理/终结的无法访问的对象,有时它被调用,但没有保证GC让对象finalize()完全调用.

所以我刚刚带来了另一个复杂的解决方案,我只是倒计时并跟踪线程正在使用它不起作用的对象,但我知道这不是一个可靠的解决方案,我知道我将面临意想不到的结果.

我只是想知道shared_ptr<>在java中是否有相同的东西,或者是否可以通过JNI处理该对象?

有任何想法吗?

Ded*_*tor 5

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

解决它的最佳方法是:

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

一个try-with-resources使用Java包装-块:

try(resource.AddRef()) {
    // Do your thing
}
Run Code Online (Sandbox Code Playgroud)

  • 据推测,`addRef`(标准Java命名约定的方法名称以小写字母开头)应该递增计数器.另外,如果你想避免使用`synchronized`方法的开销,可以使用`java.util.concurrent.AtomicInteger`代替. (2认同)