站内搜索: 请输入搜索关键词
当前页面: 图书首页 > From Java To C# A Developers Guide

From Java To C# A Developers Guide

[ directory ] Previous Section Next Section

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.

    [ directory ] Previous Section Next Section