L'extrait de code suivant exécute deux threads, l'un est un simple enregistrement de minuterie toutes les secondes, le second est une boucle infinie qui exécute une opération de reste:
public class TestBlockingThread {
private static final Logger LOGGER = LoggerFactory.getLogger(TestBlockingThread.class);
public static final void main(String[] args) throws InterruptedException {
Runnable task = () -> {
int i = 0;
while (true) {
i++;
if (i != 0) {
boolean b = 1 % i == 0;
}
}
};
new Thread(new LogTimer()).start();
Thread.sleep(2000);
new Thread(task).start();
}
public static class LogTimer implements Runnable {
@Override
public void run() {
while (true) {
long start = System.currentTimeMillis();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// do nothing
}
LOGGER.info("timeElapsed={}", System.currentTimeMillis() - start);
}
}
}
}
Cela donne le résultat suivant:
[Thread-0] INFO c.m.c.concurrent.TestBlockingThread - timeElapsed=1004
[Thread-0] INFO c.m.c.concurrent.TestBlockingThread - timeElapsed=1003
[Thread-0] INFO c.m.c.concurrent.TestBlockingThread - timeElapsed=13331
[Thread-0] INFO c.m.c.concurrent.TestBlockingThread - timeElapsed=1006
[Thread-0] INFO c.m.c.concurrent.TestBlockingThread - timeElapsed=1003
[Thread-0] INFO c.m.c.concurrent.TestBlockingThread - timeElapsed=1004
[Thread-0] INFO c.m.c.concurrent.TestBlockingThread - timeElapsed=1004
Je ne comprends pas pourquoi la tâche infinie bloque tous les autres threads pendant 13,3 secondes. J'ai essayé de changer les priorités des threads et d'autres paramètres, rien n'a fonctionné.
Si vous avez des suggestions pour résoudre ce problème (y compris la modification des paramètres de changement de contexte du système d'exploitation), veuillez me le faire savoir.
-Djava.compiler=NONE
, cela ne se produira pas.
-XX:+PrintCompilation
j'obtiens ce qui suit à la fin du délai prolongé: TestBlockingThread :: lambda $ 0 @ 2 (24 octets) COMPILE SKIPPED: boucle infinie triviale (réessayer à un niveau différent)