内在锁定和同步

时间:2017-01-26 14:23:06

标签: java multithreading concurrency

我目前正在oracle.com上阅读Intrinsic Locks and Synchronization,其中我来到了这个特定的例子:

  

同步语句对于通过细粒度同步提高并发性也很有用。例如,假设类MsLunch有两个实例字段c1c2,它们永远不会一起使用。必须同步这些字段的所有更新,但没有理由阻止c1的更新与c2的更新交错 - 这样做会通过创建不必要的阻塞来减少并发性。我们不是使用同步方法或使用与此相关联的锁,而是仅创建两个对象来提供锁。

public class MsLunch {
    private long c1 = 0;
    private long c2 = 0;
    private Object lock1 = new Object();
    private Object lock2 = new Object();

    public void inc1() {
        synchronized(lock1) {
            c1++;
        }
    }

    public void inc2() {
        synchronized(lock2) {
            c2++;
        }
    }
}

在本节之前,synchronized方法解释如下:

public synchronized void increment() {
    this.c++;
}

应该是哪个,请纠正我,如果我错了,就像

一样
public void increment() {
    synchronized(this) {
        c++;
    }
}

如果我没有向increment()添加功能,那是正确的吗?

我现在的问题来自短语:

  

但没有理由阻止c1更新{em> interleaved 更新c2

我不确定我是否完全理解“ interleaved ”在此上下文中的含义。是否意味着,如果我是从lock2示例中移除MsLunch

public class MsLunch {
    private long c1 = 0;
    private long c2 = 0;
    private Object lock1 = new Object();
    // private Object lock2 = new Object(); // 'lock2' is no more!

    public void inc1() {
        synchronized(lock1) {
            c1++;
        }
    }

    public void inc2() {
        synchronized(lock1) { // Using 'lock1' here too
            c2++;
        }
    }
}

我可能遇到锁定问题?假设thread-1遇到inc1(),从lock1获取锁定,但在能够增加或释放锁定之前会被暂停。现在thread-2正在输入inc2(),其中为lock1创建了另一个锁。这是通过使用另一个lock2来避免的,这就是我不能简单地使用this作为锁定提供者的原因吗?换句话说:这会导致问题吗?

1 个答案:

答案 0 :(得分:3)

这里有两个锁可以独立增加c1c2,而不会在释放锁时等待。因此,如果Thread-1进入c1中的同步块并获得lock1,则另一个Thread-2可以增加c2而无需等待thread-1锁。

需要注意的重要事项:

使用this作为共享监视器存在一个问题,因为MsLunch实例上的引用在MsLunch之外可见。例如。 Thread-3能够获得此类之外的synchronized (msLunchInstance)锁。

相关问题