8.4. Volatile fields

Like Java, C# has a volatile keyword for modifying fields only. This special modifier is usually used only in multi-threaded programming. Threads might cache the values of member fields for efficiency and, since threads can share the same field, it might be possible that a particular thread's cache field value is out of sync with the actual field's value. This is especially so if other concurrently running threads update the field of a shared object.

In both Java and C#, declaring a field as volatile tells the compiler that it should not attempt to perform optimizations (such as caching) on the field. The system always reads the current (latest) value of a volatile field at the point it is requested, and writes the value of the field immediately on assignment.

You declare a field as volatile by inserting the volatile keyword in front, as with all other modifiers. The following statement declares temp as a public static int variable which is also volatile: public static volatile int temp;

Like Java

  • You inform the compiler not to optimize a shared field by declaring it as volatile.

  • You should declare fields which are shared by multiple concurrently-running threads as volatile – this is especially so if this field is not synchronized within a lock block. [8]

    [8] A C# lock block is similar to a synchronized block in Java. A locked block is protected by an object mutex, and can only be assessed by any single thread at only one time. See Chapter 17.

Additional notes

  • A volatile field cannot be passed to a ref or out parameter of a method (see section 7.2.2).

    The following will cause a compilation error:

     1: class TestClass{
     2:    private volatile int MyInt;
     3:
     4:    public void DoThis(ref int i){
     5:    }
     6:
     7:    public static void Main(){
     8:      TestClass tc = new TestClass();
     9:      tc.MyInt = 3;
    10:     tc.DoThis(ref tc.MyInt);
    11:   }
    12:  }
    

    Compilation error:

    test.cs(10,19): error CS0676: Cannot pass volatile field
    'TestClass.MyInt' as ref or out, or take its address
    
  • A volatile field cannot be read-only as well. The following declaration results in the compilation error 'A field can not be both volatile and readonly':

    public readonly volatile bool b;
    

    Likewise, you cannot declare a constant as volatile. [9]

    [9] A volatile constant doesn't make sense since you cannot change a constant's value.

  • The type of a field marked as volatile can only be of the following:

    - any reference type;

    - a pointer type (within an unsafe context) – see section 9.1;

    - the following simple (primitive) types only: sbyte, byte, short, ushort, int, uint, char, float, bool;

    - an enum (see Chapter 25) type with an enum base type of sbyte, byte, short, ushort, int and uint.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.144.102.69