古典的な例は次のとおりです。あなたが操作の二つのスレッドを持っている想像し、それらの両方は、同じ方法で参照:globalVar
は、このメソッドはと対話し、設定できることを他のいくつかの事前定義された数である
public void addToGlobalVar(int y) {
int x = globalVar; //what if a thread stops right after this line?
x += y;
globalVar = y;
}
を。 globalVarは、あなたが完全に1が停止し、他のCPU時間を取得し、正確なナノ秒を知っていることはありませんので、スレッドは、ある程度任意ベースで計算時間を得る50
であると言うことができます。
この例では、UIスレッドに加えてAsyncTaskを起動し、ある時点で両方ともaddToGlobalVar(10)
を使用すると、そのコードブロックの2行目で1つのスレッドが中断される可能性があります。他のスレッドがスリープしている間に他のスレッドが通過すると、globalVarは60に正常に設定されます。しかし、もう一方のスレッドが起動すると、x = 50と考えられ、60に設定されます。 50 + 10 + 10 = 60となりました。これがどのように問題になるのかが分かります。
この単純な例を修正するには、計算アトミック(x、1行、すべての計算をスキップしてスキップ)を実行するか、論理が1行に凝縮できなかった場合、を使用してください。
1行に収まるという理由だけでは、アトミックまたはスレッドセーフではありません。 – Coeffect