如何确保线程在终止时安全地解锁锁,而所有方法已经处理它?

huangapple go评论76阅读模式
英文:

How can I guarantee a thread is safely unlocking a lock upon termination, while all methods already handle it?

问题

一个服务器项目可能会运行很长时间并创建许多线程。
在以下代码中,我在方法 setData(MyData data) 中询问自己是否除了总体的 try catch 外,还需要保护锁(lock)本身:

注意:假设它是线程安全的,我不太熟悉可能导致线程终止的其他原因或自然灾害,比如 Windows 7 的限制之类的。(我不贪心,使用大约 ±5 个线程,但仍然)

public class MyFactory {

private ReadWriteLock rwl = new ReentrantReadWriteLock();
    private Lock readLock = rwl.readLock();
    private Lock writeLock = rwl.writeLock();
    
    private static MyFactory _instance = new MyFactory();
    private static Map<Integer, MyData> mapDatas = new HashMap<>();
    
    public static MyFactory getInstance() {
        return _instance;
    }
    
    
    public void setData(MyData data) {
        writeLock.lock();   
        try {
            mapData.put(...);
        } catch (Exception exc) {
            ...
        } finally {
            writeLock.unlock();
        }
    }
英文:

A server project, might run for very long time and create many threads.
In the following code I ask myself do i have to protect the lock somehow in addition to an overall try catch in method setData(MyData data):

note: assuming its thread-safe, i am not really familiar with other reasons or natural disasters that may cause thread termination, like windows 7 limitations or so. (i am not greedy, using +-5 threads, but still)

public class MyFactory {

private ReadWriteLock rwl = new ReentrantReadWriteLock();
    private Lock readLock = rwl.readLock();
    private Lock writeLock = rwl.writeLock();
    
    private static MyFactory _instance = new MyFactory();
    private static Map&lt;Integer, MyData&gt; mapDatas = new HashMap&lt;&gt;();
    
    public static MyFactory getInstance() {
        return _instance;
    }
    
    
    public void setData(MyData data) {
        writeLock.lock();   
        try {
            mapData.put(...);
        } catch (Exception exc) {
            ...
        } finally {
            writeLock.unlock();
        }
    }

答案1

得分: 1

假设您从不将锁暴露给其他对象,并且始终在finally块中使用unlock解锁锁定,那么就没有问题。

原因在于,finally块中的代码在try块或catch块中发生任何情况时都会被_始终_调用。即使抛出了Error,这也是真的。例如,当您内存不足或某个DLL存在链接错误时,就会发生这些情况。如果发生了比Error更糟糕的情况,那很可能也会结束您的进程,并使问题无关紧要。

英文:

Assuming that you never expose the lock to other objects and you always use unlock the lock in a finally block, you are fine.

The reason is that the code in the finally block is always called if something happens in the try or catch blocks. Even if an Error is thrown this is true. These happen for example when you're out of memory or there is a linkage error with some DLL. If something worse happens than an Error, that will likely also end your process and make the problem moot.

huangapple
  • 本文由 发表于 2020年10月18日 07:05:02
  • 转载请务必保留本文链接:https://go.coder-hub.com/64408182.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定