关于Java引用和synchronized关键字的实践的问题?

时间:2011-02-24 10:36:53

标签: java reference synchronized

很长一段时间我对引用和synchronized关键字的问题感到困惑。 我经常看到这样的代码:

Class someClass {
    ...
    private SomeObject mObject;
    ...
    public void someMethod() {
        ...
       final SomeObject obj = mObject;
       ...
       //then use the 'obj' variable rather than mObject
       ...
    }

}

我的问题是为什么要使用局部最终变量obj来替换成员变量?    为什么不直接使用成员变量?

我还看到一些与'synchronized'关键字相关的示例代码,如下所示:

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);
}

为什么这些代码可以实现同步目标?     谢谢!

4 个答案:

答案 0 :(得分:0)

就第一个问题而言,它确保方法无法修改对象,通过将其别名化为最终变量,确保您以后不会重新分配某些内容?我不确定......

第二个问题: 这是有效的,因为如果没有连接mState,那么我们从方法返回并且r.write()不会被执行。它使用对象本身作为锁。

答案 1 :(得分:0)

在第一个例子中,我认为这个想法是在最终的局部变量中获取成员变量的副本,这样如果在另一个线程上更改了成员变量,则成员函数中的副本将保持不变。 / p>

第二个例子类似于它在局部变量中获取当前连接线程的副本。

想象一下,如果成员变量(或连接的线程)被直接访问,然后通过另一个线程的函数调用进行部分更改,则可能会发生未定义的行为。

我确定这个编码模式有一个名字,但我记不住了!

答案 2 :(得分:0)

从我对你的问题和第一个例子的理解,代码试图通过想要获取成员变量的本地副本来避免线程问题。第一个例子没有这样做,它只是获取一个新的局部变量,指向成员变量指向的同一个对象,但实际上并没有保护该对象上的调用不受线程问题的影响。

编辑以下@ Nick的评论:像Nick说的那样,第一个例子的someMethod方法避免了mObject被中途的另一个实例替换的可能性。但是,它不会通过同一实例上的并发调用来防止线程问题。

答案 3 :(得分:0)

1> 我想你的第一个问题是......成员变量没有被直接使用,因为该引用对象也可以用在其他一些方法中......而在其他方法中,它可能不需要被声明为final,就像您已经显示的方法....所以最好创建该变量的本地引用.....

2 - ; 假设使用线程同时访问某个引用对象....现在,如果该对象修改了某些数据,则该数据的并发访问完整性将丢失....因此要求该对象引用存在某种锁定所以,当一个线程访问该对象的一个​​引用时,其他一些线程应该无法访问它....所以这个synchronized关键字用于实现...