この記事では、Java マルチスレッドにおける volatile および synchronized の使用法を例とともに分析します。皆さんの参考に共有してください。具体的な実装方法は以下の通りです。
次のようにコードをコピーします。
public class Volatiletest extends Thread {
プライベート静的整数カウント = 0;
public void run() {
カウント++;
}
public static void main(String[] args) {
スレッド thread[] = 新しいスレッド [10000];
for (int i = 0; i < thread.length; i++) {
スレッド[i] = 新しい Volatiletest();
}
for (int i = 0; i < thread.length; i++) {
スレッド[i].start();
}
試す {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(count);
}
}
コードは上記のとおりです。期待される出力は 10000 です。ただし、count++ はスレッドセーフではないため、出力は 10000 未満になることがよくあります。
この問題を解決するために、volatile キーワードが追加されました。
次のようにコードをコピーします。
public class Volatiletest extends Thread {
プライベート volatile static int カウント = 0;
public void run() {
カウント++;
}
public static void main(String[] args) {
スレッド thread[] = 新しいスレッド [10000];
for (int i = 0; i < thread.length; i++) {
スレッド[i] = 新しい Volatiletest();
}
for (int i = 0; i < thread.length; i++) {
スレッド[i].start();
}
試す {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(count);
}
}
修正後は10000以外の値が出力されることが多いです。
これを同期形式に変更します。コードは次のとおりです。
次のようにコードをコピーします。
public class SynchronizedTest extends Thread {
プライベート静的整数カウント = 0;
public void run() {
同期済み (LockClass.lock) {
カウント++;
}
}
public static void main(String[] args) {
スレッド thread[] = 新しいスレッド [10000];
for (int i = 0; i < thread.length; i++) {
スレッド[i] = 新しい SynchronizedTest();
}
for (int i = 0; i < thread.length; i++) {
スレッド[i].start();
}
試す {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(count);
}
}
次のようにコードをコピーします。
パブリック クラス LockClass {
public static byte[] lock = 新しい byte[0];
}
この変更後の出力は 10000 になります。
これは、volatile キーワードがまったく役に立たないことを意味しますか?スレッドの安全性を保証できるのは同期のみですか?
例証します:
Java 言語には、同期ブロック (またはメソッド) と揮発性変数という 2 つの固有の同期メカニズムが含まれています。どちらのメカニズムもコード スレッドの安全性を実現するために提案されています。揮発性変数は同期性が低く (ただし、より単純でコストが低い場合もあります)、その使用はエラーも発生しやすくなります。 Java 言語の揮発性変数は「同期性が低い」と考えることができます。同期化されたブロックと比較すると、揮発性変数は必要なコーディングが少なく、実行時のオーバーヘッドも少なくなりますが、機能性は同期化の一部にすぎません。
つまり、場合によっては、volitile の方が synchronized よりも使いやすいですが、当然ながら、synchronized の方が劣ります。
この記事が皆さんの Java プログラミングに役立つことを願っています。