是“开关"吗?语句评估线程安全? [英] Is the "switch" statement evaluation thread-safe?

查看:20
本文介绍了是“开关"吗?语句评估线程安全?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

考虑以下示例代码:

class MyClass
{
    public long x;

    public void DoWork()
    {
        switch (x)
        {
            case 0xFF00000000L:
                // do whatever...
                break;

            case 0xFFL:
                // do whatever...
                break;

            default:
                //notify that something going wrong
                throw new Exception();
        }
    }
}

忘记代码片段的无用性吧:我怀疑的是 switch 语句的行为.

Forget the uselessness of the snippet: my doubt is about the behavior of the switch statement.

假设 x 字段只能有两个值:0xFF00000000L0xFFL.上面的开关不应该属于默认"选项.

Suppose that the x field could have only two values: 0xFF00000000L or 0xFFL. The switch above should not fall into the "default" option.

现在假设一个线程正在执行x"等于 0xFFL 的开关,因此第一个条件将不匹配.同时,另一个线程将x"变量修改为0xFF00000000L.我们知道 64 位操作不是原子操作,因此变量将首先将低位双字清零,然后将高位双字清零(反之亦然).

Now imagine that one thread is executing the switch with "x" equal to 0xFFL, thus the first condition won't match. At the same time, another thread modifies the "x" variable to 0xFF00000000L. We know a 64-bit operation is not atomic, so that the variable will have the lower dword zeroed first, then the upper set afterward (or vice versa).

如果切换中的第二个条件在x"为零时(即在新分配期间)完成,我们是否会陷入不希望的默认"情况?

If the second condition in the switch will be done when the "x" is zero (i.e. during the new assignment), will we fall into the undesired "default" case?

推荐答案

您实际上是在发布两个问题.

You're actually posting two questions.

线程安全吗?

好吧,显然不是,当第一个线程进入 switch 时,另一个线程可能会改变 X 的值.由于没有锁定且变量不是 volatile,您将根据错误的值进行切换.

Well, obviously it is not, another thread might change the value of X while the first thread is going into the switch. Since there's no lock and the variable is not volatile you'll switch based on the wrong value.

您是否会按下开关的默认状态?

Would you ever hit the default state of the switch?

从理论上讲,您可能会这样做,因为更新 64 位不是原子操作,因此理论上您可以跳到赋值的中间并获得 x 的混合结果,正如您指出的那样.这在统计上不会经常发生,但最终会发生.

Theoretically you might, as updating a 64 bits is not an atomic operation and thus you could theoretically jump in the middle of the assignment and get a mingled result for x as you point out. This statistically won't happen often but it WILL happen eventually.

但是开关本身是线程安全的不是线程安全的是读取和写入 64 位变量(在 32 位操作系统中).

But the switch itself is threadsafe, what's not threadsafe is read and writes over 64 bit variables (in a 32 bit OS).

想象一下,你有以下代码而不是 switch(x):

Imagine instead of switch(x) you have the following code:

long myLocal = x;
switch(myLocal)
{
}

现在切换是在局部变量上进行的,因此,它是完全线程安全的.当然,问题在于 myLocal = x read 和它与其他赋值的冲突.

now the switch is made over a local variable, and thus, it's completely threadsafe. The problem, of course, is in the myLocal = x read and its conflict with other assignments.

这篇关于是“开关"吗?语句评估线程安全?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆