# 同步方法

> 原文： [https://docs.oracle.com/javase/tutorial/essential/concurrency/syncmeth.html](https://docs.oracle.com/javase/tutorial/essential/concurrency/syncmeth.html)

Java 编程语言提供两种基本同步习语：_ 同步方法 _ 和 _ 同步语句 _。下两节将介绍两个同步语句中较为复杂的语句。本节介绍同步方法。

要使方法同步，只需将`synchronized`关键字添加到其声明中：

```
public class SynchronizedCounter {
    private int c = 0;

    public synchronized void increment() {
        c++;
    }

    public synchronized void decrement() {
        c--;
    }

    public synchronized int value() {
        return c;
    }
}

```

如果`count`是`SynchronizedCounter`的实例，那么使这些方法同步有两个影响：

*   首先，对同一对象的两个同步方法的调用不可能进行交错。当一个线程正在为对象执行同步方法时，所有其他线程调用同一对象的同步方法（暂停执行）直到第一个线程完成对象。
*   其次，当同步方法退出时，它会自动与 _ 建立与同一对象的同步方法的任何后续调用 _ 之前发生的关系。这可以保证对所有线程都可以看到对象状态的更改。

请注意，构造函数无法同步 - 将`synchronized`关键字与构造函数一起使用是语法错误。同步构造函数没有意义，因为只有创建对象的线程在构造时才能访问它。

* * *

**Warning:** When constructing an object that will be shared between threads, be very careful that a reference to the object does not "leak" prematurely. For example, suppose you want to maintain a `List` called `instances` containing every instance of class. You might be tempted to add the following line to your constructor:

```
instances.add(this);

```

But then other threads can use `instances` to access the object before construction of the object is complete.

* * *

同步方法支持一种简单的策略来防止线程干扰和内存一致性错误：如果一个对象对多个线程可见，则对该对象变量的所有读取或写入都是通过`synchronized`方法完成的。 （一个重要的例外：`final`字段，在构造对象后无法修改，可以通过非同步方法安全地读取，一旦构造了对象）这种策略是有效的，但可能会带来[活跃度的问题](liveness.html)，我们将在本课后面看到。