ホームページ  >  記事  >  Java  >  Java マルチスレッドでの volatile および synchronized の使用状況分析

Java マルチスレッドでの volatile および synchronized の使用状況分析

高洛峰
高洛峰オリジナル
2017-01-05 16:02:511766ブラウズ

この記事では、Java マルチスレッドにおける volatile および synchronized の使用法を例とともに分析します。皆さんの参考に共有してください。具体的な実装方法は以下の通りです:

package com.chzhao;
public class Volatiletest extends Thread {
    private static int count = 0;
    public void run() {
        count++;
    }
    public static void main(String[] args) {
        Thread threads[] = new Thread[10000];
        for (int i = 0; i < threads.length; i++) {
            threads[i] = new Volatiletest();
        }
        for (int i = 0; i < threads.length; i++) {
            threads[i].start();
        }
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(count);
    }
}

コードは上記の通りです。期待される出力は 10000 です。すると、count++ はスレッドセーフではないため、出力は 10000 未満になることがよくあります。

この問題を解決するには、 volatile キーワードが追加されます。

package com.chzhao;
public class Volatiletest extends Thread {
    private volatile static int count = 0;
    public void run() {
        count++;
    }
    public static void main(String[] args) {
        Thread threads[] = new Thread[10000];
        for (int i = 0; i < threads.length; i++) {
            threads[i] = new Volatiletest();
        }
        for (int i = 0; i < threads.length; i++) {
            threads[i].start();
        }
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(count);
    }
}

修正後、10000以外の値が出力されることが多いです。

同期形式に変更されたコードは次のとおりです:

package com.chzhao;
public class SynchronizedTest extends Thread {
    private static int count = 0;
    public void run() {
        synchronized (LockClass.lock) {
            count++;
        }
    }
    public static void main(String[] args) {
        Thread threads[] = new Thread[10000];
        for (int i = 0; i < threads.length; i++) {
            threads[i] = new SynchronizedTest();
        }
        for (int i = 0; i < threads.length; i++) {
            threads[i].start();
        }
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(count);
    }
}
package com.chzhao;
public class LockClass {
    public static byte[] lock = new byte[0];
}

この変更後、出力は 10000 になります。

これは volatile キーワードがまったく役に立たないことを意味しますか?スレッドの安全性を確保できるのは同期のみですか?

説明:

Java 言語には、同期ブロック (またはメソッド) と揮発性変数という 2 つの固有の同期メカニズムが含まれています。どちらのメカニズムもコード スレッドの安全性を実現するために提案されています。揮発性変数は同期性が低く (ただし、より単純でコストが低い場合もあります)、その使用はエラーも発生しやすくなります。 Java 言語の揮発性変数は、同期ブロックに比べて「同期性が低い」と考えることができます。揮発性変数は必要なコーディングが少なく、実行時のオーバーヘッドも少なくなりますが、機能は同期化の一部にすぎません。

つまり、場合によっては、同期よりも揮発性の方が使いやすいですが、もちろん同期は悪くなります。

この記事が皆さんの Java プログラミングに役立つことを願っています。

Java マルチスレッドにおける揮発性および同期された使用状況分析に関するその他の記事については、PHP 中国語 Web サイトに注目してください。


声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。