[解決済み] != チェックスレッドは安全か?
2022-05-29 20:42:16
質問
のような複合演算は知っています。
i++
はスレッドセーフではありません。
複数の
演算を含むため、スレッドセーフではありません。
しかし、自分自身との参照をチェックすることは、スレッドセーフな操作なのでしょうか?
a != a //is this thread-safe
これをプログラムして、複数のスレッドを使おうとしましたが、失敗しませんでした。私のマシンではレースをシミュレートできなかったようです。
EDITです。
public class TestThreadSafety {
private Object a = new Object();
public static void main(String[] args) {
final TestThreadSafety instance = new TestThreadSafety();
Thread testingReferenceThread = new Thread(new Runnable() {
@Override
public void run() {
long countOfIterations = 0L;
while(true){
boolean flag = instance.a != instance.a;
if(flag)
System.out.println(countOfIterations + ":" + flag);
countOfIterations++;
}
}
});
Thread updatingReferenceThread = new Thread(new Runnable() {
@Override
public void run() {
while(true){
instance.a = new Object();
}
}
});
testingReferenceThread.start();
updatingReferenceThread.start();
}
}
これは、スレッドセーフをテストするために使用しているプログラムです。
変な挙動
私のプログラムがいくつかの反復の間に開始されると、出力フラグの値を取得します。
!=
のチェックは同じ参照で失敗します。しかし、いくつかの反復の後、出力は一定の値になります。
false
になり、さらに長時間プログラムを実行しても、一度も
true
の出力が得られない。
出力が示すように、いくつかのn(固定ではない)反復の後、出力は一定の値であり、変化しないようです。
出力です。
いくつかのイテレーションに対して
1494:true
1495:true
1496:true
19970:true
19972:true
19974:true
//after this there is not a single instance when the condition becomes true
どのように解決するのですか?
同期がない場合、このコード
Object a;
public boolean test() {
return a != a;
}
は
true
. のバイトコードです。
test()
ALOAD 0
GETFIELD test/Test1.a : Ljava/lang/Object;
ALOAD 0
GETFIELD test/Test1.a : Ljava/lang/Object;
IF_ACMPEQ L1
...
を読み込んでいるのがわかるように、フィールド
a
をローカル変数に二度ロードします。これは非アトミックな操作で、もし
a
が別のスレッドで変更された場合、比較の結果
false
.
また、メモリの可視性の問題がありますが、これは
a
への変更が、現在のスレッドから見えるという保証はありません。
関連
-
[解決済み】Android "ビュー階層を作成した元のスレッドだけが、そのビューに触れることができる"
-
[解決済み] 他のスレッドからGUIを更新するにはどうすればよいですか?
-
JQuery DataTable 详解
-
ローカルリソースのロードが許可されていない場合の解決策
-
[解決済み] JavaにおけるHashMapとHashtableの違いは何ですか?
-
[解決済み] Javaにおけるpublic、protected、package-private、privateの違いは何ですか?
-
[解決済み] Javaにおける "implements Runnable "と "extends Thread "の違いについて
-
[解決済み] アトミック属性と非アトミック属性の違いは何ですか?
-
[解決済み] プロセスとスレッドの違いは何ですか?
-
[解決済み] instanceofを呼び出す前にnullチェックは必要ですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
Java のエラーです。未解決のコンパイル問題 解決方法
-
eclipse アクセス制限です。タイプ 'xxx' は API ではありません(必須ライブラリ '' の制限)。
-
Javaクラスローダーにソースコードから潜り込む
-
Enumとの組み合わせでswitchの使い方を一度覚えるために必要な定数式
-
コンストラクタの呼び出しは、コンストラクタのエラー理解の最初のステートメントである必要があります。
-
Spring boot runs with Error creating bean with name 'entityManagerFactory' defined in class path resource
-
エラーの解決方法 jarfile XXX.jarにアクセスできません。
-
[オリジナル】java学習ノート【II】よくあるエラー クラスパス上のクラスファイルが見つからない、またはアクセスできない場合
-
Exception: java.util.NoSuchElementException: 行が見つかりません
-
java -serverコマンドで「Error: no `server' JVM at ... jvm.dll」を解決する方法です。