2012-09-19 15 views
6

スレッド作成リスナーをJavaで記述することはできますか?例えばaopを使って?スレッド作成リスナー

私のアプリケーションがスレッドを作成した場合、自分のテーブル、コンテナなどにこのオブジェクトを登録したいと思うということです。

+1

メインスレッドに 'ClassLoader'を登録した場合、そのスレッドがすべての新しいスレッドに継承され、うまくいけばスレッドが何らかのクラスをロードする必要があります。つまり、' ClassLoader'が参照され、スレッドを登録する機会.... – Saintali

+0

私はリスナーのために必要なメソッドで 'Thread'を拡張する道を行くでしょう。もちろん、あなたのコードに対してのみ動作します。 – SJuan76

+0

移行を追跡する必要がありますか(「新しいスレッドが作成され、すぐに対応する必要があります」など)、またはアプリケーションで作成されたスレッドの一覧などがあれば十分です。特定の時点(「今、スレッドを知り、何かをしたい」など) – Fildor

答えて

1

私は、これはAOP(例えば、AspectJの)で可能になると思います。ただし、アスペクトコンパイラでJDKクラスを再コンパイルできる場合を除き、独自のThreadThreadGroup/Executorの型を作成する必要があります。スレッドの起動時に登録する場合は、スレッドのstartメソッドにポイントカットを定義し、スレッドオブジェクトの作成時に登録する場合は、プールのcreateThreadにポイントカットを定義します。そして、あなたがしたいのですが何をしてアドバイスを使用することができますすべてのスレッドがThread.startで開始され ので、その方法のためのポイントカットを記述します。


次は、アスペクトコンパイラでJDKを再コンパイルする場合にのみ機能します。もちろん、これは完璧ではない。 cachedThreadPoolエグゼキュータは各タスクの新しいスレッドを開始しないかもしれませんが、Thread.startではなくRunnable.runCallable.callにポイントカットを登録すると、十分かもしれません。

+0

これはスレッドの実行には有効ですが、実行中のスレッドではなく作成されたスレッドでリッスンすることが重要です。 – user454322

+0

@ user454322いいえ。アドバイス前のAは、スレッドの開始時に呼び出されます。 (つまり、これら3つのメソッドのどれかが呼び出されます) – zeller

+0

スレッド_が開始される前に呼び出されることは理解されていますが、スレッド_が作成されたときに呼び出されることはありますか? たとえば、スレッドが作成されたが、_started_されない場合はどうなるでしょうか? – user454322

4

私は、JVM上のすべての実行中スレッドを継続的に一覧表示するスレッドを作成します。
新しいスレッドが出現したことを通知するたびに、どちらの方法でもコードのクラスを通知します。

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

  2. Listing All Running Threads

=========:ここ

は、現在JVM上で実行されているすべてのスレッドの一覧を表示する方法についていくつかのリンクがあります===

開始コード:

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

これらの例は良いと便利ですが、リスナーはありません動作。私は新しいスレッドがjvmによって作成されるという情報を持っていたいと思います。何も上書きせずに 'instatntly'と言いましょう。 –

+0

@ŁukaszRzeszotarski上記の例からリスナービヘイビアを実装することはできますが、これは作成したスレッドではなくスレッドを実行することです(質問したとおり)。 – user454322

1

おそらくThreadGroupが必要なものです。すべてのスレッドはThreadGroupのメンバーであり、新しいスレッドを開始すると、デフォルトではそのグループと同じグループに追加されます。

理論的には、スレッドがグループに追加または削除されたときに通知される可能性のある(推奨されない)サブクラスです。

このグループのスレッドをポーリングするか、すべてのスレッドをポーリングする方が良い解決策です。

+0

作成時または起動時にスレッドグループにスレッドが追加されますか? –

+0

コードからは、コードが開始された時点が示唆されます。スレッドが作成されたときを知りたければ、スレッドをサブクラス化し(そしてスレッド作成コードをすべて変更する) –

関連する問題