2 votes

Récupérer tous les threads en attente d'un objet avant d'appeler notifyAll

J'ai un tas de code et le processeur est petit,
lors de l'appel notifyAll Je veux donc savoir quels sont les threads qui attendent actuellement que l'objet soit libéré.

synchronized (obj){
//do some stuff..
obj.notifyall();
}

Je veux imprimer tous les threads qui attendent que l'objet soit libéré avant d'appeler obj.notifyAll()

7voto

Sanjay T. Sharma Points 12620

Est-ce que tous les fils attendent la ressource pour la même condition ? Si oui, vous pouvez essayer de remplacer obj.notify() au lieu de obj.notifyAll bien que ce ne soit pas recommandé. A ma connaissance, il n'existe aucun moyen de "récupérer" une liste de tous les threads en attente sur un objet donné (bien que vous puissiez obtenir par programme un thread-dump du processus et visualiser les threads, mais je suis sûr que ce n'est pas ce que vous aviez à l'esprit). Même si c'était le cas, lister les threads et ensuite faire "quelque chose" avec eux prendrait sûrement plus de temps que le temps pris pour notifyAll .

De même, si le "processeur est petit", essayez de limiter le nombre de threads créés, car sans une quantité raisonnable de "vrais" threads, la création d'un trop grand nombre de threads est généralement une surcharge. De cette façon, notifyAll ne réveillerait pas un tas de fils.

Voici un petit programme qui démontre le vidage des informations sur l'état des threads avec des commentaires en ligne :

package net.sanjayts.test;

import java.lang.management.ManagementFactory;
import java.lang.management.ThreadInfo;
import java.util.concurrent.TimeUnit;

public class ThreadDumpTest {

    public static void main(String[] args) throws Exception {
        final Object lock = new Object();
        for (int i = 0; i < 6; ++i) {
            final int cnt = i;
            new DaemonThread(new Runnable() {
                @Override
                public void run() {
                    try {
                        // If counter is even, try to acquire common lock and then
                        // sleep. If odd, sleep without trying to acquire the lock.
                        // This way, if we do a thread dump, we'll see threads in
                        // different states (TIMED_WAIT for those sleeping threads
                        // and BLOCKED for those waiting for the common "lock".
                        if (cnt % 2 == 0) {
                            synchronized (lock) {
                                TimeUnit.MINUTES.sleep(1); // sleep 1 min
                            }
                        } else {
                            TimeUnit.MINUTES.sleep(1); // sleep 1 min
                        }
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }, "mythread-" + cnt).start();
        }
        ThreadInfo[] infos = ManagementFactory.
                getThreadMXBean().dumpAllThreads(true, true);
        for (ThreadInfo info : infos) {
            System.out.println(info);
            System.out.println("===========================");
        }
        TimeUnit.SECONDS.sleep(2);
    }

}

class DaemonThread extends Thread {
    public DaemonThread(Runnable r, String name) {
        super(r, name);
        setDaemon(true);
    }
}

2voto

Peter Lawrey Points 229686

Vous pouvez utiliser Thread.getAllStackTraces() et afficher tous les threads en attente.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X