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?
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).