这种同步有什么意义?

时间:2009-12-30 21:40:05

标签: java android synchronization

这里的同步有什么意义?

为什么不使用mConnectedThread.write(out)

代码段来自Android (found here)

的BluetoothChat示例
    /**
 * Write to the ConnectedThread in an unsynchronized manner
 * @param out The bytes to write
 * @see ConnectedThread#write(byte[])
 */
public void write(byte[] out) {
    // Create temporary object
    ConnectedThread r;
    // Synchronize a copy of the ConnectedThread
    synchronized (this) {
        if (mState != STATE_CONNECTED) return;
        r = mConnectedThread;
    }
    // Perform the write unsynchronized
    r.write(out);
}

3 个答案:

答案 0 :(得分:2)

需要进行同步以确保您没有不一致的状态。

没有同步,代码将是:

public void write(byte[] out) {
    if (mState != STATE_CONNECTED) return;
    mConnectedThread.write(out);
}

现在,如果在语句调用执行之前,if语句检查和方法调用之间的连接可能会被分配为null mConnectedThread。这将导致NullPointerException

答案 1 :(得分:1)

每当两个线程访问相同的数据(此处为变量mStatemConnectedThread)时,他们必须使用“内存屏障”来确保可见性。看来mStatemConnectedThread的原子性在这里也很重要。

可见性意味着一个线程所做的更改对另一个线程可见。优化可能会导致值被缓存,以便更改仅对创建它们的线程可见。同步导致任何写入都反映在主内存中,并且任何读取都会绕过本地缓存并对主内存进行。从理论上讲,如果没有同步,一个线程可以设置mStatemConnectedThread,但其他线程可能永远不会“看到”这些更改,并等待该条件发生变化。

原子性意味着无法单独观察多个动作。从另一个线程的角度来看,没有发生任何更改,或者发生了所有更改。因此,例如,另一个线程永远不会看到mStateSTATE_CONNECTED,但在分配之前请先阅读mConnectedThread

答案 2 :(得分:1)

需要锁才能保持一致性。 将mConnectedThread复制到单独的变量是因为写入 - 这是一个可能的长度操作 - 可以在锁之外完成。