我目前正在oracle.com上阅读Intrinsic Locks and Synchronization,其中我来到了这个特定的例子:
同步语句对于通过细粒度同步提高并发性也很有用。例如,假设类MsLunch有两个实例字段
c1
和c2
,它们永远不会一起使用。必须同步这些字段的所有更新,但没有理由阻止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
作为锁定提供者的原因吗?换句话说:这会导致问题吗?
答案 0 :(得分:3)
这里有两个锁可以独立增加c1
和c2
,而不会在释放锁时等待。因此,如果Thread-1
进入c1
中的同步块并获得lock1
,则另一个Thread-2
可以增加c2
而无需等待thread-1
锁。
需要注意的重要事项:
使用this
作为共享监视器存在一个问题,因为MsLunch
实例上的引用在MsLunch
之外可见。例如。 Thread-3
能够获得此类之外的synchronized (msLunchInstance)
锁。