我想知道在声明变量as volatile
和始终访问synchronized(this)
Java 中的块中的变量之间的区别?
根据这篇文章,http://www.javamex.com/tutorials/synchronization_volatile.shtml有很多要说的,但也有很多不同之处,但也有一些相似之处.
我对这条信息特别感兴趣:
...
- 对volatile变量的访问永远不会阻塞:我们只进行简单的读或写操作,因此与synchronized块不同,我们永远不会持有任何锁;
- 因为访问volatile变量永远不会持有锁,所以它不适合我们想要读取update-write作为原子操作的情况(除非我们准备"错过更新");
read-update-write是什么意思?写入也不是更新,还是仅仅意味着更新是依赖于读取的写入?
最重要的是,何时更适合声明变量volatile
而不是通过synchronized
块访问变量?使用volatile
依赖于输入的变量是一个好主意吗?例如,有一个变量被称为render
通过渲染循环读取并由按键事件设置?
假设我有一个全局对象:
class Global {
public static int remoteNumber = 0;
}
Run Code Online (Sandbox Code Playgroud)
有一个线程定期运行以从远程获取新号码,并更新它(仅写入):
new Thread {
@override
public void run() {
while(true) {
int newNumber = getFromRemote();
Global.remoteNumber = newNumber;
Thread.sleep(1000);
}
}
}
Run Code Online (Sandbox Code Playgroud)
并且有一个或多个线程remoteNumber
随机使用这个全局(只读):
int n = Global.remoteNumber;
doSomethingWith(n);
Run Code Online (Sandbox Code Playgroud)
你可以看到我没有使用任何锁或synchronize
保护它,对吗?是否有任何可能导致问题的潜在问题?
更新:
就我而言,读取线程必须实时获取最新的新值并不重要。我的意思是,如果有任何问题(由于缺少锁/同步导致)使一个读取线程错过了该值,这并不重要,因为它很快就会有机会运行相同的代码(可能在循环中)
但是不允许读取未确定的值(我的意思是,如果旧值为 20,则新的更新值为 30,但读取线程读取的值不存在,例如 33,我不确定是否可能)