JavaにおけるVolatileの役割

1875 ワード

https://blog.csdn.net/u010412719/article/details/46683029
JavaのVolatileの役割はいくつかのブログを見て、理解していないことに気づいたが、簡単に言えば、私たちのマルチスレッド開発では、ある変数や属性をVolatileキーワードで限定すると、スレッドは変数を使用するたびに、変数修正後の最新の値、すなわちVolatileキーワードが変数の可視性を保証することを読み取る.しかし、変数の原子性を保証することはできません.これにより、volatileキーワードの誤用が同時に発生した場合、結果は私たちの予想とは異なり、次のコードが見られます.
package com.wrh.firstpro;
public class TestVolatile {
public volatile static int count = 0;

public static void inc() {

    //    1  ,      
    try {
        Thread.sleep(1);
    } catch (InterruptedException e) {
    }

    count++;
}

public static void main(String[] args) {

    //    1000   ,   i++  ,      

    for (int i = 0; i < 1000; i++) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                TestVolatile.inc();
            }
        }).start();
    }

    //      10  ,                         
    try {
        Thread.sleep(10*1000);
    } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    //              ,   1000
    System.out.println("    :Counter.count=" + TestVolatile.count);
}

}
上記の結果は、実行するたびに値が異なる場合があります.1000の場合があります.理由:
可視性の場合、Javaはvolatileキーワードを提供して可視性を保証します.共有変数がvolatileによって修飾されると、変更された値がすぐにプライマリ・メモリに更新され、他のスレッドが読み取りを必要とすると、メモリから新しい値が読み出されます.一方、通常の共有変数は可視性を保証できません.通常の共有変数が変更された後、いつホストメモリに書き込まれるかは不確定であり、他のスレッドが読み取られると、メモリに元の古い値が残る可能性があるため、可視性を保証できません.また、synchronizedとLockによっても可視性が保証され、synchronizedとLockは、同じ時点で1つのスレッドだけがロックを取得して同期コードを実行することを保証し、ロックを解除する前に変数の変更をプライマリ・メモリにリフレッシュすることができる.したがって、可視性を保証できます.
しかし、volatileは変数の操作が原子性であることを保証することができず、これが上の根本的な原因となっている.具体的な説明はこのブログを見ることができます.http://www.cnblogs.com/dolphin0520/p/3920373.html(私が見たいくつかのブログでvolatileのキーワードの説明が一番はっきりしています)ここも見ることができます.http://www.cnblogs.com/aigongsi/archive/2012/04/01/2429166.html