現在、並行性、特に "volatile"キーワードを勉強しようとしています。すべてカウンター変数揮発性を宣言しJava - 揮発性が期待どおりに機能しない
は変数はすぐにメインメモリに書き戻されますカウンタに書き込みます。また、カウンタのすべての読み取りは、メインメモリから直接読み取られます。カウンタ変数の揮発性の宣言は、その後だけでなく、揮発性変数自体がメインメモリに書き込まれ
と
スレッドがvolatile変数への書き込み
を、どのように見えるかここです。また、volatile変数に書き込む前にスレッドによって変更された他のすべての変数もメインメモリにフラッシュされます。スレッドがvolatile変数を読み込むと、volatile変数と一緒にメインメモリにフラッシュされた、メインメモリから他のすべての変数も読み込まれます。
出典:tutorials.jenkov.com | Java Concurrency - Java Volatile Keyword私は結論になり
/私は揮発性変数に対して行った変更は、常にすべてのスレッドに表示されることを前提としています。だから、私はそれをテストするコードを作る。
TestClass
package org.personal.test1;
class TestClass {
public static int w = 0;
public static int x = 0;
public static int y = 0;
public static volatile int z = 0;
private static final int ITERATIONS = 100000;
public static void sooPlus(int indents) {
for (int i = 0; i < TestClass.ITERATIONS; i++) {
TestClass.w++;
TestClass.x++;
TestClass.y++;
TestClass.z++;
}
}
public static void sooMinus(int indents) {
for (int i = 0; i < TestClass.ITERATIONS; i++) {
TestClass.w--;
TestClass.x--;
TestClass.y--;
TestClass.z--;
}
}
public static synchronized String getVariableValues() {
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("(");
stringBuilder.append("w : "+TestClass.w+", ");
stringBuilder.append("x : "+TestClass.x+", ");
stringBuilder.append("y : "+TestClass.y+", ");
stringBuilder.append("z : "+TestClass.z+")");
return stringBuilder.toString();
}
}
Main Class
package org.personal.test1;
/**
* <ol type="I">
* <li>
* <a href="http://tutorials.jenkov.com/java-concurrency/volatile.html">jenkov.com - Java Volatile Keyword</a>
* </li>
* </ol>
*/
public class Main {
public static void main(String[] args) {
Main.call1();
}
private static void call1() {
Main.test1();
}
private static void test1() {
Thread thread1 = new Thread("Thread1") {
@Override
public void run() {
TestClass.sooPlus(1);
}
};
Thread thread2 = new Thread("Thread2") {
@Override
public void run() {
TestClass.sooMinus(4);
}
};
thread1.start();
thread2.start();
try {
thread1.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
try {
thread2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(TestClass.getVariableValues());
}
}
私が得る結果は、私が期待していたものではありませんでした。
何私が手にすることは、私が期待してい何
(w : -2314, x : -1692, y : -1416, z : -1656)
(変わる)
(w : 0, x : 0, y : 0, z : 0)
または少なくとも
(w : -2314, x : -1692, y : -1416, z : 0)
質問
- 私が予想よりも異なる出力の結果、間違った結論を/何を前提としたのですか?
- テスト方法が間違っていましたか?はいの場合は、どうすれば修正できますか?
- (オプション)推奨するJava並行処理に関する良いチュートリアルはありますか?
ノート
- 私は同様の質問を読み込もうとしましたが、私は完全に質問者が彼の問題を理解するために行うことを試みていたかを理解することができませんでした。
volatileキーワードは、スレッドセーフな弱い形式を提供します。可視性は保証されますが、原子性や相互排除は保証されません。揮発性フィールドがスレッドセーフではない可能性はありますか?はい、フィールドへの書き込みがアトミックでない場合すべての揮発性フィールドで構成されるクラスがスレッドセーフではない可能性はありますか?はい、フィールドへの書き込みによって無効な状態遷移が発生した場合(同期がないため) – scottb