1

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

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()andchangeTwo()被不同的线程调用。有一个同步块changeOne()来防止mField改变就足够了changeTwo()吗?mField或者我需要明确地将每个更改的地方包装到synchronized块中?(请留下同步方法和其他方法)。

4

2 回答 2

4

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

编辑:正如 Tedd Hopp 所建议的,如果变量不是易失性读取,则还需要同步和锁定,你应该在同一个对象上。

于 2012-12-28T06:12:59.523 回答
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) {
              ...
         }
    }

同步方法更紧凑,而同步块更灵活。使用同步块,您可以锁定任何对象,而使用同步方法,您可以隐式锁定 onthis或静态方法 on class

于 2012-12-28T06:20:39.473 回答