2015年4月13日 星期一

[JAVA] java memory mode with "volatile" & "synchronized"

As a matter of fact, the Java memory model is such that a modification
to a variable in one thread may not immediately be visible to other threads. Actually, it
may never be visible. Consider the code in Listing 5–11: if one thread calls
MyClass.loop(), and at some point in the future another thread calls
Myclass.setValue(100), the first thread may still not terminate; may carry on looping
forever and always print out a value other than 100, simply because of the Java
language’s memory model.
Listing 5–11. Java Memory Model Impact
public class MyClass {
     private static final String TAG = "MyClass";
     private static int mValue = 0;
     public static void setValue(int n) {
          mValue = n;
     }
     public static void loop () {
          while (mValue != 100) {
               try {
                    Log.i(TAG, “Value is ” + mValue);
                    Thread.sleep(1000);
               } catch (Exception e) {
                    // ignored
               }
          }
     }
}
You have two options to fix that:
Use the synchronized keyword, as shown in Listing 5–12.
Use the volatile keyword, as shown in Listing 5–13.
Listing 5–12. Adding the Synchronized Keyword
public class MyClass {
     private static final String TAG = "MyClass";
     private static int mValue = 0;
     public static synchronized void setValue(int n) {
          mValue = n;
     }
     public static synchronized int getValue() {
          return mValue;
     }
     public static void loop () {
          int value;
          while ((value = getValue()) != 100) {
          try {
               Log.i(TAG, “Value is ” + value);
               Thread.sleep(1000);
               } catch (Exception e) {
              // ignored
               }
          }
     }
}

Listing 5–13. Adding the Volatile Keyword
public class MyClass {
     private static final String TAG = "MyClass";
     private static volatile int mValue = 0; // we add the volatile keyword and remove
     the synchronize keyword
     public static void setValue(int n) {
          mValue = n; // you’d still have to use synchronized if that statement were mValue += n (not atomic)
     }
     public static void loop () {
          while (mValue != 100) {
               try {
               Log.i(TAG, “Value is ” + mValue);
               Thread.sleep(1000);
               } catch (Exception e) {
              // ignored
               }
          }
     }
}

沒有留言:

張貼留言