每个使用字段的方法中的同步块

时间:2012-12-28 06:11:20

标签: java synchronized

这似乎是一个非常常见的问题,虽然我找不到一个。假设我有这段代码:

public class MyClass {
    private AnotherClass mField;

    public void changeOne(AnotherClass newOne) {
        // <...> lines of code here
        synchronized (mField) {
            mField = newOne;
        }
        // <...> lines of code here

    }

    public void changeTwo(AnotherClass newTwo) {
        // <...> lines of code here
        mField = newTwo;
        // <...> lines of code here
    }
}

假设从不同的线程调用changeOne()changeTwo()。是否足以在changeOne()中设置同步块以保护mField不被changeTwo()更改?或者我需要明确地将mField更改为synchronized块的每个位置包装? (请留下同步方法和其他方法)。

2 个答案:

答案 0 :(得分:4)

您需要使用synchronized block(或)synchronized方法将所有修改显式同步到mField。否则,通过一次执行changeTwo,多个线程可以更改mField

编辑:正如Tedd Hopp建议的那样,如果变量不是volatile,那么读取也需要同步并锁定你应该在同一个对象上。

答案 1 :(得分:0)

不,不是,两个线程都必须尝试获取相同的锁,然后如果线程A首先获取锁,则线程B将被阻塞,直到A释放它。锁可以是A和B共有的任何对象,最典型的是

public class MyClass {
    private AnotherClass mField;

        public synchronized void changeOne(AnotherClass newOne) {
             ...
        }

        public synchronzied void changeTwo(AnotherClass newTwo) {
             ...
        }

在这种情况下this用作锁。它(几乎)等同于

    public void changeOne(AnotherClass newOne) {
         synchronized(this) {
              ...
         }
    }

    public void changeTwo(AnotherClass newOne) {
         synchronized(this) {
              ...
         }
    }

同步方法更紧凑,同步块更灵活。使用synchronized块可锁定任何对象,而使用synchronized方法可隐式锁定thisclass上的静态方法。