同步方法是否会阻止更新对象字段?
Does synchronizing method prevents objects fields being updated?
考虑以下 class。
public class Counter{
private Lock lock = new Lock();
private int count = 0;
public int inc(){
lock.lock();
int newCount = ++count;
lock.unlock();
return newCount;
}
public int incBy2() {
syncronized(this){
count+=2;
return count;
}
}
现在线程 T1 调用 inc() 方法,T2 调用 incBy2()。这里有竞争条件吗?
或者 T2 会锁定 this
,从而阻止 inc 方法调用 lock.lock()
?
存在竞争条件。您实际上是在同步两个单独的对象。两个线程可以同时进入 inc()
和 incBy2()
临界区。
对象上的监视器对该对象的其余部分没有任何影响。获取对象上的监视器不会阻止任何线程修改该对象的字段。获取锁只会阻止其他线程获取该锁。
当你写
class Foo {
public void doSomething() {
synchronized(this) {
...
}
}
}
你最好写
class Foo {
private Object lock = new Object();
public void doSomething() {
sychronized(lock) {
...
}
}
}
第一个版本不会比第二个版本更适合您。这两个版本之间的唯一区别是,在第二个版本中,如果其他对象获取 Foo 对象本身的监视器,它不会影响对 doSomething 的锁定(因此锁被封装在对象中,只能由线程调用获取) doSomething 方法)。
考虑以下 class。
public class Counter{
private Lock lock = new Lock();
private int count = 0;
public int inc(){
lock.lock();
int newCount = ++count;
lock.unlock();
return newCount;
}
public int incBy2() {
syncronized(this){
count+=2;
return count;
}
}
现在线程 T1 调用 inc() 方法,T2 调用 incBy2()。这里有竞争条件吗?
或者 T2 会锁定 this
,从而阻止 inc 方法调用 lock.lock()
?
存在竞争条件。您实际上是在同步两个单独的对象。两个线程可以同时进入 inc()
和 incBy2()
临界区。
对象上的监视器对该对象的其余部分没有任何影响。获取对象上的监视器不会阻止任何线程修改该对象的字段。获取锁只会阻止其他线程获取该锁。
当你写
class Foo {
public void doSomething() {
synchronized(this) {
...
}
}
}
你最好写
class Foo {
private Object lock = new Object();
public void doSomething() {
sychronized(lock) {
...
}
}
}
第一个版本不会比第二个版本更适合您。这两个版本之间的唯一区别是,在第二个版本中,如果其他对象获取 Foo 对象本身的监视器,它不会影响对 doSomething 的锁定(因此锁被封装在对象中,只能由线程调用获取) doSomething 方法)。