état de course: Min et Max plage d'un entier

Anmol Singh Jaggi:

On m'a récemment posé cette question dans une interview.

Étant donné le code suivant, ce sera la valeur min et max possible du nombre entier statique 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();
    }

}

Je leur ai dit que la valeur maximale serait de 25 (dans le cas où il n'y a pas de condition de course), et min serait 5 (en cas d'une condition de course entre tous les fils à chaque itération).
Mais l'enquêteur dit que la valeur min peut aller même au- dessous 5.
Comment est - ce possible?

Andy Turner:

Je revendique la valeur minimale possible est 2.

La clé est la non-atomicité num++, par exemple, il est une lecture et une écriture, qui peut avoir d' autres opérations entre les deux.

Appelez les fils T1..T5:

  • T1 indique 0, T2 indique 0;
  • T1 écrit 1 et puis lit et écrit 3 fois.
  • Puis T2 écrit 1;
  • Puis T1 lit 1;
  • Puis T2-5 faire tout leur travail
  • Puis, enfin, T1 écrit 2.

(Note: le résultat 2 ne dépend pas non plus sur le nombre de fils, ou le nombre d'itérations, à condition qu'il existe au moins deux de chaque).

Mais la réponse honnête à cette question est: il n'a pas d' importance. Il y a une course de données, telles que définies dans JLS 17.4.5 :

Lorsqu'un programme contient deux accès contradictoires (§17.4.1 [ « Deux accès à (lit ou écrit) la même variable sont dit être en conflit si au moins l' un des accès est une écriture. »]) Qui ne sont pas commandé par un arrive, avant la relation, il est dit contenir une  course de données .

(Il y a une absence de passe-avant les relations entre les actions dans les fils)

Donc, vous ne pouvez pas utilement compter sur ce qu'il fait. Il est tout simplement un code incorrect.

( De plus, je connais la réponse à ce pas à cause d'une bataille durement gagnée le débogage du code multithread ou la lecture technique profonde: Je sais cela parce que j'ai lu cette réponse avant d' ailleurs c'est un tour de salon, rien de plus, et ainsi. Demander à la valeur minimale est pas une très bonne question d'entrevue).

Je suppose que tu aimes

Origine http://43.154.161.224:23101/article/api/json?id=305657&siteId=1
conseillé
Classement