ホームページ >Java >&#&チュートリアル >マルチスレッドの同時実行に関するいくつかの問題を共有する

マルチスレッドの同時実行に関するいくつかの問題を共有する

零下一度
零下一度オリジナル
2017-06-28 09:13:081524ブラウズ

1 概要

1.volatile

は、共有データが変更されるとすぐに共有メモリ (ヒープまたはメソッド領域) に同期されることを保証します。

2. スレッドがヒープ内のデータにアクセスするプロセス

スレッドはスタック内に変数のコピーを作成し、変更後にデータをヒープに同期します。

3. 命令の並べ替え

実行効率を向上させるために、CPU は依存関係のない命令を並べ替えます。並べ替えを制御したい場合は、volatile を使用して変数を変更できます。変数を含む命令の前後の命令は独立して順序付けされ、前後の命令を交差して順序付けることはできません。

2 つの一般的な問題と解決策

1. アトミック性の問題

いわゆるアトミック性とは、操作が開始されると、操作を中断できないことを意味します。つまり、マルチスレッドの同時環境では、実行は同じ CPU タイム スライス内で完了します。同じスレッドの複数の操作が異なる CPU タイム スライスで実行される場合、途中での停滞により、一部の共有データが後続の操作中に他のスレッドによって変更される可能性があり、その変更は現在のスレッドに同期されず、データが発生します。現在のスレッドによって操作されるデータが実際のデータと一致しないという問題は、非コヒーレントな実行によって引き起こされます。この問題はアトミック性の問題と呼ばれます。 2. 可視性の問題

可視性の問題は、スレッドが共有データにアクセスする方法に関連して発生します。スレッドがヒープ (メソッド領域) 内の変数にアクセスすると、まずスタック内に変数の

コピーが作成され、変更後にそれがヒープに同期されます。スレッドがコピーを作成したばかりで、ヒープにまだ同期されていない変数を別のスレッドが変更すると、i=9 など、2 つのスレッドが同じ状態で同じ変数を操作する現象が発生します。 , 変数i 初期値は9で、各スレッドの演算はマイナス

1となります。 2 つのスレッド A と B が同時に変数にアクセスします。結果 i=8 をヒープに同期する前に、B が最初に i-1 を実行します。このとき、i=9 の状態が実行されます。 . スレッドの安全性の問題が発生しました。

スレッドの安全性の問題の理由: 1 つのスレッドによる共有データの変更は、他のスレッドからすぐには認識されません。 volatile は次の解決策を提供します: volatile によって変更された共有データをスレッドが変更すると、この変更はすぐにヒープに同期されるため、他のデータはヒープから共有データにアクセスできます
常に最新のデータを取得します複数のスレッドにわたる値。

volatile の欠点:


volatile は、スレッド がヒープからデータをコピーした場合、スレッドがヒープからデータを取得するときに、現在のすべてのスレッドの中で最新の値を取得することしか保証できません。操作が完了しました 以前は他のスレッドがデータを変更していましたが、変更されたデータは現在のスレッドに同期されません。
3. 順序付けの問題

実行効率を向上させるために、CPU は依存関係のない命令を並べ替えます。並べ替えられた実行結果は、順次実行結果と同じになります。 たとえば、ソースコード内:

int i=0;

int y=1;
CPUは、実行中に最初に「int y=1;」を実行します。 i= 0;"の場合、実行結果は逐次実行結果と同じになります。
命令の並べ替えはシングルスレッド環境では安全ですが、マルチスレッド環境では問題が発生する可能性があります。例:
スレッド A:

s=new String("sssss");//指令1flag=false;//指令2

スレッド B:
while(flag){
doSome();
}
s.toUpperCase();//指令3

スレッド A が順番に実行される場合、つまり、命令 1 を実行してから命令 2 を実行する場合、スレッド B の実行には問題はありません。命令を並べ替えた後、スレッド A が命令 2 を先に実行すると、
これは flag=true となり、スレッド 2 に切り替わり、ループを終了し、命令 3 を実行します。 s オブジェクトがまだ作成されていないため、null ポインタが例外が発生します。
順序付けの問題の原因:

たとえば、スレッド B は、スレッド A が最初に命令 1 を実行し、 次に命令 2 を実行する必要があります。この命令により、再配置は実際には必要な順序で実行されません。このとき、スレッドの安全性の問題が発生します。

解決策:

  1. 同期メカニズムを使用して、同時に 1 つのスレッドのみが共有データにアクセスできるようにしますが、これは非効率です。

  2. volatile を使用すると、命令に volatile で変更された変数が含まれており、この命令の実行順序は変更されません。この命令の前後の命令は独立して再配置できますが、相互に再配置することはできません。

参照:

以上がマルチスレッドの同時実行に関するいくつかの問題を共有するの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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