【问题标题】:Does synchronizing method prevents objects fields being updated?同步方法是否会阻止对象字段被更新?
【发布时间】:2015-01-07 20:34:33
【问题描述】:

考虑以下类。

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()

【问题讨论】:

    标签: java multithreading locking synchronized locks


    【解决方案1】:

    对象上的监视器对对象的其余部分没有任何影响。获取对象上的监视器不会阻止任何线程修改该对象的字段。获取锁只会阻止其他线程获取该锁。

    当你写作时

    class Foo {
    
        public void doSomething() { 
            synchronized(this) {
                ...
            }
        }
    }
    

    你最好写

    class Foo {
        private Object lock = new Object();
    
        public void doSomething() {
            sychronized(lock) {
                ...
            }
        }
    }
    

    第一个版本比第二个版本对你没有更多的帮助。这两个版本之间的唯一区别是,在第二个版本中,如果其他对象获取 Foo 对象本身的监视器,则不会影响对 doSomething 的锁定(因此锁定被封装在对象中,只能通过调用线程获取doSomething 方法)。

    【讨论】:

      【解决方案2】:

      存在竞争条件。您实际上是在两个单独的对象上同步。两个线程可以同时进入inc()incBy2()临界区。

      【讨论】:

      • 当我在this 上同步时,我会隐式阻止其他线程访问在这种情况下是锁定对象的字段。
      • @brain:不。约翰是对的。在此获取监视器不会拒绝另一个线程访问锁定。
      • @brainstorm 正如内森所说,但要补充。您正在阻止其他线程访问关键部分,而不是字段。在this 上同步说,任何尝试在thissynchronize 的呼叫者都必须等到我完成。如您所见,由于inc() 中没有sychronize(this),因此另一个线程不必等待。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-12-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多