c# - 线程安全通用规则

标签 c# java c++ multithreading

关于线程安全的几个问题,我认为我理解,但希望得到澄清,如果你能这么好心的话。我编程的特定语言是 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,并且只会设置从truefalse,这里没有问题。)

如果您想要更多控制,请查看 java.util.concurrent.atomic 包中的类。

关于c# - 线程安全通用规则,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6920014/

相关文章:

c# - 完全隐藏 GridView 中的元素(用作 ListView 的 View )?

java - 需要persistence.xml属性标签来设置sybase数据库驱动程序版本

java - 2 种方式的 SSL 身份验证无法使用 Apache httpclient : JAVA

java - ArrayDeque 类的字符

c++ - SDL2 侧滚动变量不累积

c# - Xml 类序列化错误

c# - 使用 VB 的 FileSystem.DeleteFile 方法无法正常工作,将文件删除到 csharp 中的回收站

JavaScript:单击复选框启用文本框

c++ - 如何使用 cppzmq 从 ROUTER 套接字向特定的 DEALER 套接字发送 ZeroMQ 消息?

c++ - 在C++ 11中使用字符串如何满足条件?