JAVA的内存模型(变量的同步)_移动开发_编程开发_程序员俱乐部

中国优秀的程序员网站程序员频道CXYCLUB技术地图
热搜:
更多>>
 
您所在的位置: 程序员俱乐部 > 编程开发 > 移动开发 > JAVA的内存模型(变量的同步)

JAVA的内存模型(变量的同步)

 2016/9/29 5:31:49  李培能  程序员俱乐部  我要评论(0)
  • 摘要:一个线程中变量的修改可能不会立即对其他线程可见,事实上也许永远不可见。在代码一中,如果一个线程调用了MyClass.loop(),将来的某个时间点,另一个线程调用了MyClass.setValue(100),第一个线程可能仍然不会终止,可能永远循环下去代码一:publicclassMyClass{privatestaticfinalStringTAG="MyClass";privatestaticintmValue=0;publicstaticvoidsetValue(intn)
  • 标签:Java 内存 同步

一个线程中变量的修改可能不会立即对其他线程可见,事实上也许永远不可见。

在代码一中,如果一个线程调用了MyClass.loop(),将来的某个时间点,另一个线程调用了MyClass.setValue(100),第一个线程可能仍然不会终止,可能永远循环下去

代码一:
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(){
        int value;
        while(value!=100){
            try{
                Log.i(TAG,"Value is "+value);
                Thread.sleep(1000);
            }catch(Exception e){
                
            }
        }
    }
}

 

上面的问题有两种解决办法:

一是使用synchronized关键字

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){
                
            }
        }
    }
}

 

二是使用volatile关键字

public class MyClass{
    private static final String TAG="MyClass";
    private static volatile int mValue=0;//添加volatile关键字
    public static void setValue(int n){
        mValue=n;//如果是mValue+=n,因为不是原子操作,还得使用synchronized
    }
    public static void loop(){
        int value;
        while(value!=100){
            try{
                Log.i(TAG,"Value is "+value);
                Thread.sleep(1000);
            }catch(Exception e){
                
            }
        }
    }
}

 

 

 

 value++不是原子的,value=1是原子的。volatile关键字只可以解决变量声明是原子的那些并发问题,如果变量不是原子的就必须使用synchronized关键字

不要在synchronized块中调用另一个对象的方法(它可能已经被锁住并等待之前用到的对象解锁),除非你能保证不会发生死锁,通常情况下只有亲手写其他对象的类的代码才敢确定不会发生死锁。

发表评论
用户名: 匿名