JavaA2Z

KAB-studio > プログラミング > JavaA2Z > volatileとは

volatile

日本語 揮発性
英語 volatile
ふりがな ぼらたいる
フリガナ ボラタイル

解説

マルチスレッド時に、フィールドの「命令単位」での同期を取るための予約語
フィールドに対して++演算子--演算子によるアクセスをう場合、フィールドへのアクセスは「1回」でできるため、同期を取る必要はないように見える。
だが、実際にはそうではない。++演算子等は、実際には「値の読み取り」「値の増加」「値の書き込み」といった手順を踏む。
マルチスレッドの場合、この3つの処理を同一のフィールドに対して複数のスレッドが同時にった場合、同期が取られず、値が誤った値に変えられてしまう。
volatileをフィールドに付けることで、この問題が解決される。++演算子--演算子によるアクセスを、同時に複数のスレッドおうとしてもその処理が終わるまでは他のスレッドが処理できないようになる。
 
ただし、使用はあまり勧められない。
この問題は、++演算子等の「読み取りと書き込みが同時にわれる」場合にのみ当てはまる。ほとんどの場合、読み取りと書き込みは別にわれ、その場合には通常の同期処理が必要となる。
また、volatileは実際には実装されていない場合があり、その場合は機能しない。

参考サイト

  • (参考サイトはありません)

(KAB-studioからのおしらせです)

サンプルプログラム(とか)サンプルを別ウィンドウで表示サンプルをクリップボードへコピー(WindowsでIEの場合のみ)

// Sample.java
public class Sample
{
    public static void main( String[] args )
    {
        OtherThread thread = new OtherThread();
        // もうひとつスレッド(スレッドB)を作ります。

        // 同時に2スレッドでアクセスします。
        thread.start();
        forint iF1 = 0; iF1 < 10000000; ++iF1 )
        {
            thread.notVolatileData++;
            thread.volatileData++;
        }

        try
        {
            // 終わるまで待ちます。
            while( thread.isCompleted == false )
            {
                Thread.sleep( 1 * 1000 );
            }

            System.out.println( "notVolatileData: " + thread.notVolatileData );
            System.out.println( "volatileData: " + thread.volatileData );

            // notVolatileData: 15802931
            // volatileData: 20000001

            // このように、volatileなフィールドはアクセス時に同期が取られます。
            // ……と言っといてなんですが、ほとんどのJava実行環境はvolatileを
            // サポートしていないので、両方とも結果が変わる可能性があります。

            // どちらにしろ、volatileは過信しない方がいいでしょう。
            // この場合であればsynchronizedで同期を取ってフィールドにアクセスしましょう。
        }
        catch( InterruptedException e )
        {
            // sleep()メソッドが途中で中断されると
            // InterruptedException例外が投げられます。
            e.printStackTrace();
        }
    }
}

/**
*   別スレッドとして実行するためのクラス。
*/
class OtherThread extends Thread
{
    /** 普通のフィールド */
    public int notVolatileData = 1;
    /** volatileフィールド。 */
    public volatile int volatileData = 1;

    /** 終了フラグ */
    public boolean isCompleted = false;
    
    /**
    *   Threadクラスのrun()メソッドを
    *   オーバーライドしたメソッド。このメソッドが
    *   別スレッドとして呼び出されます。
    */
    public void run()
    {
        forint iF1 = 0; iF1 < 10000000; ++iF1 )
        {
            notVolatileData++;
            volatileData++;
        }

        isCompleted = true;
    }
}
// Sample.java
public class Sample
{
    public static void main( String[] args )
    {
        OtherThread thread = new OtherThread();
        // もうひとつスレッド(スレッドB)を作ります。

        // 同時に2スレッドでアクセスします。
        thread.start();
        for( int iF1 = 0; iF1 < 10000000; ++iF1 )
        {
            thread.notVolatileData++;
            thread.volatileData++;
        }

        try
        {
            // 終わるまで待ちます。
            while( thread.isCompleted == false )
            {
                Thread.sleep( 1 * 1000 );
            }

            System.out.println( "notVolatileData: " + thread.notVolatileData );
            System.out.println( "volatileData: " + thread.volatileData );

            // notVolatileData: 15802931
            // volatileData: 20000001

            // このように、volatileなフィールドはアクセス時に同期が取られます。
            // ……と言っといてなんですが、ほとんどのJava実行環境はvolatileを
            // サポートしていないので、両方とも結果が変わる可能性があります。

            // どちらにしろ、volatileは過信しない方がいいでしょう。
            // この場合であればsynchronizedで同期を取ってフィールドにアクセスしましょう。
        }
        catch( InterruptedException e )
        {
            // sleep()メソッドが途中で中断されると
            // InterruptedException例外が投げられます。
            e.printStackTrace();
        }
    }
}

/**
*   別スレッドとして実行するためのクラス。
*/
class OtherThread extends Thread
{
    /** 普通のフィールド */
    public int notVolatileData = 1;
    /** volatileフィールド。 */
    public volatile int volatileData = 1;

    /** 終了フラグ */
    public boolean isCompleted = false;
    
    /**
    *   Threadクラスのrun()メソッドを
    *   オーバーライドしたメソッド。このメソッドが
    *   別スレッドとして呼び出されます。
    */
    public void run()
    {
        for( int iF1 = 0; iF1 < 10000000; ++iF1 )
        {
            notVolatileData++;
            volatileData++;
        }

        isCompleted = true;
    }
}

この単語を含むページ

「みだし」に含まれているページ

「解説」に含まれているページ

「サンプルプログラムとか」に含まれているページ

はてなブックマーク 詳細を表示 はてなブックマーク ブックマーク数
livedoorクリップ 詳細を表示 livedoorクリップ ブックマーク数
Yahoo!ブックマーク 詳細を表示 users
del.icio.us 登録する RSSに登録
サンプルを別ウィンドウで表示
サンプルをクリップボードへコピー(WindowsでIEの場合のみ)
update:2005/06/06
このページは、Javaプログラミング言語についての用語を網羅した辞書「JavaA2Z」の一ページです。
詳しくは「JavaA2Z」表紙の説明をご覧ください。