在多线程环境中,我有一个有趣的内存泄漏案例。 我有以下逻辑:
public void update(string key, CustomObj NewResource)
{
//fetch old resource for the given key from the concurrent hashmap
// update hashmap with the newResource for the given key
// close the old resource to prevent memory leak
}
public void read (string key)
{
// return resource for the given key
}
现在,如果我有两个线程:
线程#1:调用更新方法来更新密钥K的资源
线程2:调用read方法读取相同密钥K的资源。
注意:CustomObj属于第三方库,因此我无法在其中放置finalize方法来关闭它。
即使在读取和更新方法上使用同步也无济于事,因为更新线程可以在读取线程仍在使用资源时关闭资源。
在这种情况下,您能告诉我如何在不导致内存泄漏的情况下保持线程安全吗?
答案 0 :(得分:1)
出于任何原因,都不要使用finalize()
。
如果多个线程可以同时使用一个对象,则可以使用“引用计数”来跟踪何时应关闭资源。
当前与该对象一起使用的每个线程/函数/等在获得对对象的访问权限时,其“用户数”都会增加一。当它停止使用它时,它的“用户数”减一。将计数减为零的线程将关闭该对象。您可以利用Java标准库提供的各种“原子”原语来创建无锁解决方案。
由于这是第三个pary库中的对象,因此您需要创建某种包装程序来跟踪引用。
PS:通常,在线程间使用具有共享状态的对象不是一个好主意-会带来麻烦-同步问题,数据竞争,同步性能下降等。