很长一段时间我对引用和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);
}
为什么这些代码可以实现同步目标? 谢谢!
答案 0 :(得分:0)
就第一个问题而言,它确保方法无法修改对象,通过将其别名化为最终变量,确保您以后不会重新分配某些内容?我不确定......
第二个问题: 这是有效的,因为如果没有连接mState,那么我们从方法返回并且r.write()不会被执行。它使用对象本身作为锁。
答案 1 :(得分:0)
在第一个例子中,我认为这个想法是在最终的局部变量中获取成员变量的副本,这样如果在另一个线程上更改了成员变量,则成员函数中的副本将保持不变。 / p>
第二个例子类似于它在局部变量中获取当前连接线程的副本。
想象一下,如果成员变量(或连接的线程)被直接访问,然后通过另一个线程的函数调用进行部分更改,则可能会发生未定义的行为。
我确定这个编码模式有一个名字,但我记不住了!
答案 2 :(得分:0)
从我对你的问题和第一个例子的理解,代码试图通过想要获取成员变量的本地副本来避免线程问题。第一个例子没有这样做,它只是获取一个新的局部变量,指向成员变量指向的同一个对象,但实际上并没有保护该对象上的调用不受线程问题的影响。
编辑以下@ Nick的评论:像Nick说的那样,第一个例子的someMethod方法避免了mObject被中途的另一个实例替换的可能性。但是,它不会通过同一实例上的并发调用来防止线程问题。
答案 3 :(得分:0)
1> 我想你的第一个问题是......成员变量没有被直接使用,因为该引用对象也可以用在其他一些方法中......而在其他方法中,它可能不需要被声明为final,就像您已经显示的方法....所以最好创建该变量的本地引用.....
2 - ; 假设使用线程同时访问某个引用对象....现在,如果该对象修改了某些数据,则该数据的并发访问完整性将丢失....因此要求该对象引用存在某种锁定所以,当一个线程访问该对象的一个引用时,其他一些线程应该无法访问它....所以这个synchronized关键字用于实现...