私は最近のインタビューで、この質問をしました。
次のコードを考えると、何が静的な整数の最小値と最大値は可能でしょうかnum
?
import java.util.ArrayList;
import java.util.List;
public class ThreadTest {
private static int num = 0;
public static void foo() {
for (int i = 0; i < 5; i++) {
num++;
}
}
public static void main(String[] args) throws Exception{
List<Thread> threads = new ArrayList<Thread>();
for (int i = 0; i < 5; i++) {
Thread thread = new Thread(new Task());
threads.add(thread);
thread.start();
}
for (int i = 0; i < 5; i++) {
threads.get(i).join();
}
// What will be the range of num ???
System.out.println(ThreadTest.num);
}
}
class Task implements Runnable {
@Override
public void run() {
ThreadTest.foo();
}
}
私は(場合には何の競合状態が存在しない)の最大値が25になると彼らに言った、とminは5(反復ごとに、すべてのスレッド間の競合状態の場合)になります。
しかし、インタビュアーは、最小値がさえ5.下に行くことができると述べた
ことが可能であるどのように?
私は、可能な最小値は2であると主張しています。
これの鍵は、非アトミックであるnum++
、すなわち、それは、間に他の操作を有していてもよい、読み取りおよび書き込みです。
スレッドT1..T5を呼び出します。
- T1はT2が0を読み取り、0を読み出します。
- T1は1を書き込み、その後、3回の読み込みと書き込みをします。
- その後、T2は1を書き込みます。
- その後、T1は1を読み込み。
- そして、T2-5は、自分の仕事のすべてを行います
- そして、最後に、T1は2を書き込みます。
(注:結果2のいずれか依存しないスレッドの数、又は反復の数、それぞれの少なくとも2が提供されます。)
しかし、これに正直な答えは:それは本当に重要ではありません。で定義されたデータ競合はありJLS 17.4.5:
プログラムが含まれている場合には、相反する2つのアクセス(§17.4.1[「アクセスの少なくとも一方が書き込みである場合、2つはの読み書きを行う(へのアクセス)同じ変数が矛盾していると言われています。」])発注されません事前発生関係によって、含まれていると言われている データ競合を。
(の欠如があるたまたま、前のスレッド内のアクション間の関係)
あなたが有効に何に頼ることができないので、それはありません。これは単に不正なコードです。
(また、私はしませんので、マルチスレッドコード、または深い技術的な読書をデバッグするいくつかのハードウォンの戦いのこれに対する答えを知っている:私は他の場所の前にこの答えを読んで持っているので、私はこのことを知っているそれはパーラートリックです、何よりも、となる。求めて最小値は)非常に良い面接の質問ではありません。