2014-12-17 10 views
6

Ich habe einen Thread, der eine Drittanbieter-Lib ausführen wird, die auch ihre eigenen Threads ausführen wird. Wenn die run-Methode meines Threads beendet ist, werden Threads von Drittanbietern noch nicht fertiggestellt.Java - Warten auf Threads von Drittanbietern zu beenden

Also, was ist der beste Weg, um meinen Thread zu halten, bis diese externen Threads noch laufen?

+0

Sie brauchen eine Art Referenz, auf die Sie warten müssen. Wie ein Thread, eine Zukunft oder die Möglichkeit, einen Rückruf zu installieren. Wenn die Bibliothek das nicht anzeigt, wird es schwer ... Vielleicht etwas, das Sie alle X Sekunden abfragen können? – Thilo

+0

Ich könnte es abfragen, aber woher weiß ich, dass sie fertig sind? Kann ich die nach mir erzeugten Threads "ausspionieren"? – bsferreira

+0

Ich meine Umfrage, bis Sie etwas sehen, das Ihnen sagt, dass diese Threads getan haben, was sie tun müssen. Sind Sie sicher, dass die Bibliothek keine Unterstützung für irgendeine Art von Benachrichtigung bietet? Sie können bessere Antworten erhalten, wenn Sie uns sagen können, welche Bibliothek das ist. – Thilo

Antwort

4

Wenn Sie eine Anwendung und müssen nicht über Security Einschränkungen Sorge, und wenn Sie bereit sind, gelegentlich Ihren Code zu ändern, wenn der Code von Drittanbietern aktualisiert wird, können Sie die Einrichtungen von ThreadGroup, um die Threads zu durchlaufen und sie anhand des Namens oder der Threadgruppe zu identifizieren, die sie enthält.

Sobald Sie die Threads gefunden haben, ist es eine einfache Aufgabe, sie entweder zu überwachen, bis sie fertig sind, oder Thread.join() entsprechend zu verwenden.

Als Beispiel hier einige Arbeitscode, der alle Fäden in der JVM-Dumps:

public void printThreads(PrintWriter wtr) { 
    ThreadGroup  root; 

    totGroups=0; 
    totThreads=0; 

    for(root=Thread.currentThread().getThreadGroup(); root.getParent()!=null; root=root.getParent()) {} 
    wtr.println("Thread Dump:"); 
    printThreadGroup(wtr,root," "); 
    wtr.println(" -- Total Groups: "+totGroups+", Total Threads: "+totThreads); 
    } 

public void printThreadGroup(PrintWriter wtr, ThreadGroup grp, String pfx) { 
    try { 
     Thread[]  thds; 
     ThreadGroup[] grps; 

     totGroups++; 
     wtr.println(pfx+"Group: "+grp.getName()+", "+(grp.isDaemon()?"Daemon":"Normal")+", "+(grp.isDestroyed()?"Destroyed":"Alive")+", "+grp.getMaxPriority()); 
     thds=new Thread[grp.activeCount()]; 
     grp.enumerate(thds,false); 
     Arrays.sort(thds,THREAD_SORTER); 
     for(int xa=0; xa<thds.length && thds[xa]!=null; xa++,totThreads++) { 
      Thread   thd=thds[xa]; 
      wtr.println(pfx+". - ["+thd.getName()+", "+(thd.isDaemon()?"Daemon":"Normal")+", "+(thd.isAlive()?"Alive":"Not Started or Dead")+", "+thd.getPriority()+"]"); 
      } 

     grps=new ThreadGroup[grp.activeGroupCount()]; 
     grp.enumerate(grps,false); 
     Arrays.sort(grps,GROUP_SORTER); 
     for(int xa=0; xa<grps.length && grps[xa]!=null; xa++) { 
      printThreadGroup(wtr,grps[xa],(pfx+". ")); 
      grps[xa]=null; 
      } 
     } 
    catch(Throwable thr) { 
     wtr.println(" Cannot print threads ("+thr+")"); 
     } 
    } 

public void printStacks(PrintWriter wtr) { 
    wtr.println("Thread Stack Traces:"); 
    try { javaMx.printStacks(wtr); } catch(Throwable thr) { wtr.println(" Cannot print stacks ("+thr+")"); } 
    wtr.println(" --"); 
    } 
0

Betrachten wir die Erstellung eines Thread Set, vielleicht AbstractList<Thread>. Immer wenn Sie ein neues Thread erstellen, fügen Sie es zu Ihrem Set hinzu. Wenn Ihre Eltern Thread möchte seinen Job beenden, so etwas wie:

for (int i = 0; i < childrenThreads.size(); i++) { 
    childrenThreads.get(i).join(); 
} 

Ich verstehe, dass diese Idee, nur an sich Threads die Finalisierung der Kinder löst, aber wenn Sie verwenden den gleichen Mechanismus für die Kinder Thread s und ihre Kinder und so weiter, dann wird die

childrenThreads.get(i).join(); 

wird für den warten i'th Kind Thread, was wiederum für sein Kind Threads in einer transitiven Warte warten.

+0

Ich verstehe, was Sie tun, aber ich erschaffe das Kind nicht direkt. Ich sage nur, dass mein Thread ausgeführt werden soll und es werden die libs sein, die innerhalb der run-Methode aufgerufen werden, die tatsächlich ihre eigenen Threads erstellen. – bsferreira

4

Ich habe einen Thread, der einen Dritten lib laufen, die ihre eigenen Themen wird auch ausgeführt werden.

@Lawrence Dol Antwort erklärt, dass Sie ThreadGroup können die Gruppenstruktur und finden Sie alle Live-Threads zu durchqueren ... sofern Ihre Anwendung nicht Sandbox ist. Sie haben dann das Problem herauszufinden, welche Threads zu der 3rd-Party-Bibliothek gehören, aber es besteht eine gute Chance, dass Sie dies heuristisch tun können; z.B. basierend auf Thread-Namen.

Aber der Punkt, den ich möchte, ist, dass eine Bibliothek, die Hintergrund-Threads feuert bis zu Arbeit zu tun, und bietet keine Möglichkeit für die Arbeit zu Ende zu warten ist schlecht konzipiert:

  • Ich würde aussehen bei der API-Spezifikation für die Bibliothek, um festzustellen, ob sie bereits eine eigene Lösung dafür bietet; z.B. Eine "shutdown" -Methode, die darauf wartet, dass die Worker-Threads beendet werden.

  • Wenn nicht, dann kontaktieren Sie die Bibliotheksbetreuer und fragen Sie sie, wie sie mit der Situation umgehen sollen. Der "Workaround" mit Thread-Gruppen ist ein zerbrechlicher Hack.

  • Wenn dies keine Ergebnisse liefert und die Bibliothek Open Source ist, sollten Sie eine API-Erweiterung kodieren und sie als Patch einreichen.

0

Vielleicht nicht eine Antwort auf Ihre Frage, aber wenn ich eine Bibliothek geschrieben, die Threads erstellt, würde ich

A) Verwenden Sie einen Thread sie zu erstellen, und ein Mittel für meine Kunden das liefern ThreadFactory-Instanz und

B) Geben Sie eine .shutdown()-Methode (oder einen ähnlichen Namen), die sauber heruntergefahren, und nicht zurück, bis alle Threads gestorben sind.

Ich weiß nicht über die Bibliothek, die Sie verwenden.

Verwandte Themen