synchronized(foo){
//code
}
假设另一个使用另一个代码块访问此foo对象的线程。那会发生什么?
如果锁定在foo对象上,那么即使代码不在此关键部分,也无法访问foo对象。
如果锁定在这个代码块上,那么只有两个线程不能同时运行这个代码块。但是仍然可以使用另一个块代码来访问foo对象。
锁定对象或锁定代码,这是真的吗?
答案 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)
这是对象监视器的锁定。它阻止了此代码块的另一个线程的并发执行,以及任何其他需要锁定对象监视器的代码块。但是,它不会阻止从执行代码的线程访问对象,该代码不需要锁定对象的监视器。