关于java critical section和lock,锁定对象/数据还是锁定代码?

时间:2014-04-06 09:31:20

标签: java multithreading

 synchronized(foo){
   //code
 }

假设另一个使用另一个代码块访问此foo对象的线程。那会发生什么?

如果锁定在foo对象上,那么即使代码不在此关键部分,也无法访问foo对象。

如果锁定在这个代码块上,那么只有两个线程不能同时运行这个代码块。但是仍然可以使用另一个块代码来访问foo对象。

锁定对象或锁定代码,这是真的吗?

3 个答案:

答案 0 :(得分:3)

同步对象不会阻止任何线程访问此对象。它可以防止其他线程执行任何代码块,这些代码块也在同一个对象上同步。

所以,如果你有

public class Foo {
}

public class SharedState
    private final Foo foo = new Foo();

    private long value;

    public void increment() {
        synchronized (foo) {
            value++;
        }
    }

    public long getValue() {
        synchronized (foo) {
            return value;
        }
    }
}

然后,如果一个线程当前正在递增或获取该值,则其他线程将无法同时递增或读取该值。

如果添加方法

public Foo getFoo() {
    return foo;
}

SharedState,任何线程都可以调用它,并同时调用任何foo方法。

答案 1 :(得分:1)

synchronized(foo)语句在foo引用的对象上同步。

它不会锁定foo,但会锁定foo监视器。访问对象foo的其他线程可以毫无问题地执行此操作,如果它们不同步的话。

synchronized块中一次只能有一个线程在指向foo的对象上同步。

所以你必须要小心,只有在foo的监视器上受到锁定的保护时才能访问可能发生竞争条件的变量。

(但即使您进行同步,仍然会出现许多问题)

答案 2 :(得分:1)

这是对象监视器的锁定。它阻止了此代码块的另一个线程的并发执行,以及任何其他需要锁定对象监视器的代码块。但是,它不会阻止从执行代码的线程访问对象,该代码不需要锁定对象的监视器。