可能性のある複製:
スレッドセーフとはどういう意味ですか?
どのクラスもスレッドセーフであると非常に混乱しています。私は、クラスがスレッドセーフである場合、そのメソッドに特定の(同期された)ものがあることを理解しています。それは正しいか間違っていますか?その意味について詳しく説明してください。
Sethが述べたように、スレッドセーフとは、問題が発生することなく、メソッドまたはクラスインスタンスを複数のスレッドで同時に使用できることを意味します。
次の方法を検討してください。
_private int myInt = 0;
public int AddOne()
{
int tmp = myInt;
tmp = tmp + 1;
myInt = tmp;
return tmp;
}
_
スレッドA
とスレッドB
は両方ともAddOne()
を実行したいと考えています。ただし、A
は最初に開始され、myInt (0)
の値をtmp
に読み込みます。何らかの理由で、スケジューラはスレッドA
を停止し、スレッドB
に実行を延期することにしました。スレッドB
は、myInt
の値(まだ_0
_)も独自の変数tmp
に読み込むようになりました。スレッドB
はメソッド全体を終了するため、最終的に_myInt = 1
_になります。そして_1
_が返されます。スレッドA
の番です。スレッドA
は続きます。そして、tmp
に_1
_を追加します(tmp
は、スレッドA
に対して_0
_でした)。そして、この値をmyInt
に保存します。 myInt
は再び_1
_です。
したがって、この場合、メソッドAddOne()
が2回呼び出されましたが、メソッドがスレッドセーフな方法で実装されていないため、myInt
の値は予想どおり_2
_ではありません。ただし、_1
_は、最初のスレッドが更新を完了する前に2番目のスレッドが変数myInt
を読み取るためです。
スレッドセーフなメソッドの作成は、些細なケースでは非常に困難です。そして、かなりの数のテクニックがあります。 Javaでは、メソッドをsynchronizedとマークできます。これは、特定の時間に1つのスレッドのみがそのメソッドを実行できることを意味します。他のスレッドはインラインで待機します。メソッドスレッドセーフですが、メソッドで多くの作業が必要な場合、これは多くの時間を浪費します。別の手法は、メソッドのごく一部のみをマークすることですロックまたはセマフォを作成し、この小さな部分(通常はクリティカルセクションと呼ばれます)をロックすることにより、as synchronized()。ロックレススレッドセーフとして実装されるメソッドもあります。複数のスレッドが問題を引き起こすことなく同時に複数のスレッドをレースできるように構築されているため、メソッドが1つのアトミックコールのみを実行する場合がこれに該当します。一度に1スレッドずつ。
スレッドセーフとは、単に、問題を引き起こすことなく複数のスレッドから同時に使用できることを意味します。これは、任意のリソースへのアクセスが同期されることを意味する場合があります。