Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
335 views
in Technique[技术] by (71.8m points)

.net - Multithreading and booleans

I have a class that contains a boolean field like this one:

public class MyClass
{
    private bool boolVal;
    public bool BoolVal
    {
        get { return boolVal; }
        set { boolVal = value; }
    }
}

The field can be read and written from many threads using the property. My question is if I should fence the getter and setter with a lock statement? Or should I simply use the volatile keyword and save the locking? Or should I totally ignore multithreading since getting and setting boolean values atomic?

regards,

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

There are several issues here.

The simple first. Yes, reading and writing a boolean variable is an atomic operation. (clarification: What I mean is that read and write operations by themselves are atomic operations for booleans, not reading and writing, that will of course generate two operations, which together will not be atomic)

However, unless you take extra steps, the compiler might optimize away such reading and writing, or move the operations around, which could make your code operate differently from what you intend.

Marking the field as volatile means that the operations will not be optimized away, the directive basically says that the compiler should never assume the value in this field is the same as the previous one, even if it just read it in the previous instruction.

However, on multicore and multicpu machines, different cores and cpus might have a different value for the field in their cache, and thus you add a lock { } clause, or anything else that forces a memory barrier. This will ensure that the field value is consistent across cores. Additionally, reads and writes will not move past a memory barrier in the code, which means you have predictability in where the operations happen.

So if you suspect, or know, that this field will be written to and read from multiple threads, I would definitely add locking and volatile to the mix.

Note that I'm no expert in multithreading, I'm able to hold my own, but I usually program defensively. There might (I would assume it is highly likely) that you can implement something that doesn't use a lock (there are many lock-free constructs), but sadly I'm not experienced enough in this topic to handle those things. Thus my advice is to add both a lock clause and a volatile directive.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...