同步对象:锁定代码与锁定对象

Synchronized Object: Locking Code vs Locking Object

假设您有两个线程可以访问同一个 public 对象。一个线程有一个读取对象字段的代码块。

synchronized(object)
{
    read object fields
}

当读取对象字段的代码在线程1中执行时,如果线程2想要更新对象的字段,是否必须等到线程1完成读取对象的字段后才能更新(例如对象是否被锁定无法访问)在执行同步代码块时被其他线程调用)?

在对象上同步不会以任何方式 "lock" 它。除非以相同的方式同步更新对象的字段,否则它很可能会与您在此处提供的阅读代码交织在一起。

不,第二个线程不会等待,除非它在同一个对象上也有一个 synchronized 块。

synchronized(object)
{
    // read object fields
}

... in other thread:

synchronized(object)
{
    // write object fields
}

同步块只保护其中的代码。因此,如果两个或多个线程尝试 运行 同步块内的代码(受同一对象监视器保护),它们将被独占执行。这意味着如果一个线程已经进入同步块,其他线程将不得不等到它退出。

Synchronized block并没有对object加锁,只是利用object的monitor来保护里面的代码。如果你想让对象的方法线程安全,那么你必须将它们声明为同步的。

synchronized getField()
synchronized setField()

现在 getField() 和 setField() 可以被多个线程安全地调用。

然而,使用 synchronized 会降低性能,您可以尝试使用 Locks,或 java.util.concurrent.atomic 中的 Atomic 类,例如 AtomicInteger、AtomicBoolean 或 AtomicReference。