在Java中同步非最终对象的正确方法

时间:2016-08-10 05:08:57

标签: java concurrency thread-safety

我试图用锁来保护对象。

由于" try..catch"的语法难以实现,我没有选择互斥锁。

浏览stackoverflow,我得出结论,这是如何正确实现我的目标:

class MyClass {
    private final Object lock = new Object();
    private Channel channel = null;

    public void setChannel() {
        synchronized (lock) {
            channel = new Channel();
            synchronized (channel) {
                // setup channel
            }
        }
    }

    public void unsetChannel() {
        synchronized (lock) {
            synchronized (channel) {
                channel.close();
            }
        channel = null;
        }
    }

    public boolean isSet() {
        synchronized (lock) {
            if (channel == null)
                return false;
            synchronized (channel) {
                return channel.isActive();
            }
        }
    }
}

但它看起来很丑陋而难以阅读......

如何提高解决方案的可读性?

2 个答案:

答案 0 :(得分:2)

您可以简化锁定策略:

class MyClass {
    private final Object lock = new Object();
    private Channel channel = null;

    public void setChannel() {
        // other code can go here

        synchronized (lock) {
            channel = new Channel();
            // setup channel
        }

        // other code can go here
    }

    public void unsetChannel() {

        // other code can go here

        synchronized (lock) {
            channel.close();
            channel = null;
        }

        // other code can go here
    }

    public boolean isSet() {
        synchronized (lock) {
            if (channel == null) {
                return false;
            }
            return channel.isActive();
        }
    }
}

实际上,lock对象保护对通道变量的任何访问。

已编辑以显示未与channel交互的其他代码可能位于锁定之外的位置。

答案 1 :(得分:0)

lock上的外锁可以保护一切。你不需要第二把锁。在保持外锁的情况下,第二个线程永远无法到达它。