- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
关于线程安全的几个问题,我认为我理解,但希望得到澄清,如果你能这么好心的话。我编程的特定语言是 C++、C# 和 Java。希望在描述特定语言关键字/功能时记住这些。
1) 1 位作者,n 位读者的案例。在 n 个线程读取变量的情况下,例如在轮询循环中,以及 1 个写入器更新此变量,是否需要显式锁定?
考虑:
// thread 1.
volatile bool bWorking = true;
void stopWork() { bWorking = false; }
// thread n
while (bWorking) {...}
在这里,仅仅有一个内存屏障就足够了吗?因为据我所知,在我上面提到的语言中,对原语的简单读写不会交错,因此不需要显式锁定,但是如果没有一些显式锁定或 volatile ,则无法保证内存一致性。我的假设在这里正确吗?
2) 假设我上面的假设是正确的,那么它只对简单的读写是正确的。即 bWorking = x... 和 x = bWorking;是唯一安全的操作吗? IE 复杂的赋值,例如一元运算符 (++, --) 在这里是不安全的,+=、*= 等...?
3) 我假设如果情况 1 是正确的,那么当只涉及赋值和阅读时,将该陈述扩展为对 n 个作者和 n 个读者也是安全的是不安全的吗?
最佳答案
对于 Java:
1) volatile
变量在每次读写时从“主内存”更新/更新到“主内存”,这意味着更新线程的更改将在下一次读取时被所有读取线程看到.此外,更新是原子的(独立于变量类型)。
2) 是的,如果您有多个编写器,则像 ++
这样的组合操作不是线程安全的。对于单个写线程,没有问题。 (volatile
关键字确保其他线程可以看到更新。)
3) 只要你只分配和读取,volatile 就足够了——但是如果你有多个写入器,你就不能确定哪个值是“最终”值,或者哪个值将被哪个线程读取。甚至写入线程本身也不能可靠地知道它们自己的值已设置。 (如果你只有boolean
,并且只会设置从true
到false
,这里没有问题。)
如果您想要更多控制,请查看 java.util.concurrent.atomic 包中的类。
关于c# - 线程安全通用规则,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6920014/
我是一名优秀的程序员,十分优秀!