Is the string property self-flowing?

A string in C # is immutable and unsafe. But what when you have a public getter property? Like this:

public String SampleProperty{ get; private set; } 

If we have two threads, the first calls โ€œgetโ€ and the second calls โ€œsetโ€ at โ€œthe sameโ€ time, what will happen?

The IMHO set should make the lock safe for the flow as follows:

 private string sampleField; private object threadSafer = new object(); public String SampleProperty{ get{ return this.sampleField; } private set{ lock(threadSafer){ sampleField = value; } } } 
+27
multithreading c #
Jan 12 '09 at 9:23
source share
5 answers

Most answers use the word atomic, as if all atomic changes were needed. This is usually not the case.

This has been mentioned in the comments, but usually not in the answers - this is the only reason I am providing this answer. (A blocking point with a larger granularity to allow things like add is also complete.)

Usually you want the read stream to display the last value of the / property variable. That which is not guaranteed by atomicity . As a short example, here's a bad way to stop the thread:

 class BackgroundTaskDemo { private bool stopping = false; static void Main() { BackgroundTaskDemo demo = new BackgroundTaskDemo(); new Thread(demo.DoWork).Start(); Thread.Sleep(5000); demo.stopping = true; } static void DoWork() { while (!stopping) { // Do something here } } } 

DoWork may well loop forever, even though writing to a boolean variable is atomic โ€” there is nothing to stop the JIT from caching the stopping value in DoWork . To fix this, you need to either lock, volatile , or use an explicit memory barrier. All this applies to string properties.

+37
Jan 12 '09 at 10:36
source share

The get / set field of the reference type (ldfld / stfld) is (IIRC) guaranteed atomic, so there should be no risk of corruption. Therefore, it must be thread safe from , which , but personally, I blocked the data at a higher level - i.e.

 lock(someExternalLock) { record.Foo = "Bar"; } 

or maybe:

 lock(record.SyncLock) { record.Foo = "Bar"; } 

This allows you to make multiple reads / updates by the same object as an atomic operation, so that other threads will not be able to get an invalid state of the object

+15
Jan 12 '09 at 9:31
source share

Setting a string is an atomic operation, that is, you either get a new string or an old string, you never get garbage.

If you do any work, for example.

 obj.SampleProperty = "Dear " + firstName + " " + lastName; 

then string concatenation occurs before the call is set, so sampleField will always be either a new line or an old one.

If, however, your string concatenation code is self-relational, for example.

 obj.SampleProperty += obj.SampleProperty + "a"; 

and where in another thread is

 obj.SampleProperty = "Initial String Value"; 

Then you will need a lock.

Suppose you are working with int. If you assign int, and any value you get from int is valid, then you don't need to block it.

However, if int is counting the number of widgets processed by two or more threads so that the count is accurate, you need to block int. This is the same situation for strings.

I have a feeling that I didnโ€™t explain it very well, I hope this helps.

thank

Bw

+4
Jan 12 '09 at 9:31
source share

It is thread safe without the need for blocking. Strings are reference types, so only the link to the string is changed. Type literature is guaranteed atomic (Int32 on 32-bit systems and Int64 on 64-bit).

0
Jan 12 '09 at 9:32
source share

The second code sample is definitely not right, because locks have the desired effect when they are used in all places where the variable is available (for both get and set), so get will also require a lock.

However, when you obtain and set a field of a reference type as a property like this, adding a lock statement does not add any value. Assignment to pointers is guaranteed to be atomic in the .NET environment, and if several threads change the property, then you have an inherent race condition in any case (where threads can see different values, this may or may not be a problem), so thereโ€™s little point in blocking .

So, for what he does, the first part of the code is fine. But whether you really want to create the inherent race conditions in a multi-threaded application is another matter.

0
Jan 12 '09 at 9:32
source share



All Articles