競合状態:整数の最小および最大範囲

AnmolシンJaggi:

私は最近のインタビューで、この質問をしました。

次のコードを考えると、何が静的な整数の最小値と最大値は可能でしょうか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つはの読み書きを行う(へのアクセス)同じ変数が矛盾していると言われています。」])発注されません事前発生関係によって、含まれていると言われている  データ競合を

(の欠如があるたまたま、前のスレッド内のアクション間の関係)

あなたが有効に何に頼ることができないので、それはありません。これは単に不正なコードです。

(また、私はしませんので、マルチスレッドコード、または深い技術的な読書をデバッグするいくつかのハードウォンの戦いのこれに対する答えを知っている:私は他の場所の前にこの答えを読んで持っているので、私はこのことを知っているそれはパーラートリックです、何よりも、となる。求めて最小値は)非常に良い面接の質問ではありません。

おすすめ

転載: http://43.154.161.224:23101/article/api/json?id=305622&siteId=1