2012-09-19 5 views
6

Ist es möglich, Thread-Erstellung Listener in Java schreiben? Zum Beispiel mit aop ?!Thread-Erstellung Listener

Ich meine so etwas, dass, wenn meine Anwendung einen Thread erstellt, ich dieses Objekt in meiner eigenen Tabelle, Container oder etwas registrieren möchte.

+1

Wenn Sie einen 'ClassLoader' im Hauptthread registrieren, wird er hoffentlich von allen neuen Threads übernommen, und hoffentlich muss jeder Thread eine Klasse laden, was bedeutet, dass Ihr' ClassLoader' konsultiert wird und Sie haben eine Gelegenheit, den Thread zu registrieren .... – Saintali

+0

Ich würde auf dem Weg der Erweiterung 'Thread' mit den erforderlichen Methoden für Hörer gehen. Natürlich funktioniert nur für Ihren Code. – SJuan76

+0

Müssen Sie den Übergang verfolgen (wie: "Im Moment wurde ein neuer Thread erstellt und ich muss sofort darauf reagieren") oder ist es genug, um eine Liste oder etwas von Threads in/durch Ihre Anwendung erstellt zu haben bestimmte Zeitpunkte (wie: "Jetzt möchte ich die Threads kennen und etwas mit ihnen machen.")? – Fildor

Antwort

1

Ich denke, das mit AOP (aspectj zum Beispiel) möglich wäre. Es ist jedoch immer noch erforderlich, eigene Thread und ThreadGroup/Executor Typen zu erstellen, es sei denn, Sie können die JDK-Klassen mit dem Aspect-Compiler neu kompilieren. Definieren Sie den Punktschnitt in der Methode start Ihres Threads, wenn Sie sich beim Starten des Threads registrieren möchten, oder auf createThread Ihres Pools, wenn Sie sich beim Erstellen der Thread-Objekte registrieren möchten.


Folgende funktioniert nur, wenn das JDK mit dem Aspekt Compiler kompiliert: Alle Themen mit Thread.start gestartet werden, so eine pointcut für diese Methode schreiben, dann können Sie Ratschläge nutzen, um zu tun, was Sie möchten. Natürlich ist dies nicht perfekt, da z.B. Ein cachedThreadPool-Executor startet möglicherweise keinen neuen Thread für jede Task, aber vielleicht, wenn Sie einen Pointcut unter und nicht unter Thread.start registrieren, reicht das vielleicht aus.

+0

Dies könnte für das Ausführen von Threads funktionieren, aber die Frage besteht darin, auf Threads zu hören, die erstellt wurden und nicht auf laufenden Threads. – user454322

+0

@ user454322 Nr. Ein vorheriger Hinweis wird aufgerufen, wenn die Threads gestartet werden. (dh jede dieser 3 Methoden werden aufgerufen) – zeller

+0

Ich verstehe, dass es vor den Threads _are gestartet_ aufgerufen wird, aber würde aufgerufen werden, wenn Threads _are_ erstellt werden? Was würde beispielsweise passieren, wenn ein Thread _created_ ist, aber nie _started_? – user454322

4

Ich würde einen Thread erstellen, der fortlaufend alle laufenden Threads auf der JVM auflistet.
Jedes Mal, wenn ein neuer Thread angezeigt wird, würde er auf diese Weise eine Klasse in Ihrem Code melden.

Hier sind einige Links, wie alle Threads momentan auf der JVM läuft zur Liste:

  1. Get a List of all Threads currently running in Java

  2. Listing All Running Threads

========= ===

Ein Startcode:

ThreadCreationListener.java

public interface ThreadCreationListener { 
    public void onThreadCreation(Thread newThread); 
} 

ThreadCreationMonitor.java

public class ThreadCreationMonitor extends Thread { 
    private List<ThreadCreationListener> listeners; 
    private boolean canGo; 

    public ThreadCreationMonitor() { 
     listeners = new Vector<ThreadCreationListener>();//Vector class is used because many threads may use a ThreadCreationMonitor instance. 
     canGo = true; 
     // Initialize the rest of the class here... 
    } 

    // Most important methods 
    public void addListener(ThreadCreationListener tcl) { 
     listeners.add(tcl); 
    } 

    public void removeListener(ThreadCreationListener tcl) { 
     listeners.remove(tcl); 
    } 

    public void run() { 
     List<Thread> runningThreads; 
     List<Thread> lastRunningThreads; 

     while(canGo) { 
      // Step 1 - List all running threads (see previous links) 
      // runningThreads = ... 

      // Step 2 - Check for new threads and notify all listeners if necessary 
      if (runningThreads.removeAll(lastRunningThreads)==true) { 
       for(Thread t : runningThreads) { 
        for(ThreadCreationListener tcl : listeners) { 
         tcl.onThreadCreation(t);//Notify listener 
        } 
       } 
      } 
     } 
    } 

    public void shutdown() { 
     canGo = false; 
    } 

}

MyThreadInfoConsumer.java

public class MyThreadInfoConsumer implements ThreadCreationListener { 
    public void onThreadCreation(Thread newThread) { 
     // Process here the notification... 
    } 
} 

Main.java

public class Main { 
    public static void main(String[] args) { 
     ThreadCreationMonitor tcm = new ThreadCreationMonitor(); 
     tcm.start(); 

     MyThreadInfoConsumer myTIC = new MyThreadInfoConsumer(); 
     tcm.addListener(myTIC); 

     // rest of your code... 
     // Don't forget to call tcm.shutdown() when exiting your application ! 
    } 
} 
+0

Diese Beispiele sind gut und nützlich, aber es gibt keinen Listener Verhalten. Ich hätte gerne die Information, dass ein neuer Thread von jvm erstellt wird, sagen wir "sofort", ohne irgendetwas zu übergehen. –

+0

@ ŁukaszRzeszotarski Sie können ein Listener-Verhalten aus den obigen Beispielen implementieren, aber sie sind zum Ausführen von Threads nicht erstellt Threads (wie Sie gefragt). – user454322

1

Vielleicht ist eine ThreadGroup das, was Sie brauchen. Alle Threads sind Mitglieder einer ThreadGroup, und wenn Sie einen neuen Thread starten, wird er standardmäßig zur selben Gruppe hinzugefügt wie seine Eltern.

Theoretisch ist es möglich (aber nicht empfohlen) zu Unterklasse benachrichtigt werden, wenn ein Thread hinzugefügt oder aus der Gruppe entfernt wird.

Es ist wahrscheinlich, dass das Abfragen der Threads dieser Gruppen oder das Abfragen aller Threads eine bessere Lösung ist.

+0

Ein Thread wird der Thread-Gruppe beim Erstellen oder beim Start hinzugefügt? –

+0

Aus dem Code schlägt es vor, wenn es gestartet wird. Wenn Sie wissen möchten, wann ein Thread erstellt wurde, müssen Sie den Thread kategorisieren (und den gesamten Thread-Erstellungscode ändern). –