7

Is it possible to write Thread creation listener in java? For example using aop?!

I mean something like this that if my application creates a thread I would like to register this object in my own table, container or something.

Łukasz Rzeszotarski
  • 5,791
  • 6
  • 37
  • 68
  • 1
    If you register a `ClassLoader` in the main thread, hopefully that will be inherited by all new threads, and again hopefully, any thread will need to load some class, which means your `ClassLoader` will be consulted and you have an opportunity to register the thread.... – Saintali Sep 19 '12 at 08:43
  • I would go by the path of extending `Thread` with the required methods for listeners. Of course, will work only for your code. – SJuan76 Sep 19 '12 at 08:44
  • Do you need to track the transition (like: "Right now a new Thread has been created and I have to react to it at once") or is it enough to have a list or something of threads created in/by your application at specific points in time (like: "Now I want to know the threads and do something with them.")? – Fildor Sep 19 '12 at 08:50
  • I would like to write my own thread monitor, so I need instantly 'current' thread objects. I'm gonna create my own decorated thread to handle all this monitoring stuff - but the problem is how to get the information that new thread is gonna created without overriding anything - 'instantly'. I would like to write a monitor that is easy to run in any application. – Łukasz Rzeszotarski Sep 19 '12 at 08:55
  • Check the guys who has written the eclipse debugger. Maybe they can give an hint for this question ;) – Stephan Sep 19 '12 at 10:15
  • Related: http://stackoverflow.com/questions/9874641/tracking-java-thread-creation-and-lifetime – Aaron Digulla Nov 11 '16 at 09:43

3 Answers3

5

I would create a thread that continously lists all running threads on the JVM.
Then each time it noticies that a new thread has appeared, it would notify in either way a class in your code.

Here are some links about how to list all threads currently running on the JVM :

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

  2. Listing All Running Threads

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

A starting code :

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 = new ArrayList<>();

        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) {
                        lastRunningThreads.add(t);
                        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 !
    }
}
Stephan
  • 41,764
  • 65
  • 238
  • 329
  • These examples are good and useful, but there is no listener behaviour. I would like to have the information that new thread is gonna created by jvm let's say 'instatntly' without overriding anything. – Łukasz Rzeszotarski Sep 19 '12 at 08:57
  • @ŁukaszRzeszotarski you can implement a listener behavior from the examples above though, they are about running threads not created threads (as you asked). – user454322 Sep 19 '12 at 09:03
2

I think this would be possible with AOP (aspectj for instance). But it is still required to create your own Thread and ThreadGroup/Executor types, unless you can recompile the JDK classes with the aspect compiler. Define the pointcut on your thread's start method if you want to register on thread launching or on the createThread of your pool if you want to register on the creation of the thread objects.


The following works only if you recompiled the JDK with the aspect compiler: All threads are started with Thread.start, so write a pointcut for that method then you can use advices to do what you'd like to. Of course this is not perfect since e.g. a cachedThreadPool executor might not start a new thread for each task, but maybe if you register a pointcut on Runnable.run and Callable.call rather than on Thread.start, that might be sufficient enough.

zeller
  • 4,904
  • 2
  • 22
  • 40
  • This might work for running threads but, the question is about listening on threads created not threads running. – user454322 Sep 19 '12 at 09:06
  • @user454322 No. A before advice will get called when the threads are started. (ie any of these 3 methods are called) – zeller Sep 19 '12 at 09:12
  • I understand that it will be called before threads _are started_, but would be called when threads _are created_? e.g., what would happen if a thread is _created_ but never _started_? – user454322 Sep 19 '12 at 09:39
  • 2
    @user454322. I see, I interpreted the question as if he wanted to register on the ' thread start' event. I edited my answer. – zeller Sep 19 '12 at 10:20
  • @zeller sounds good. And what about registering pointcut on a Thread class constructor? Would it work - something like this? What do you think? – Łukasz Rzeszotarski Sep 19 '12 at 11:04
  • That might be ok, but only if you want to listen on thread creation, not task creation. Also keep in mind that if you want to use the jdk classes, you have to compile them with aspect. But subclassing `Thread` and defining the pointcut for the new classes ctor would work. – zeller Sep 19 '12 at 11:16
1

Perhaps a ThreadGroup is what you need. All Threads are members of a ThreadGroup and when you start a new Thread it is added to the same group as its parent by default.

In theory its possible (but not recommended) to sub-class to be notified when a Thread is added or removed from the group.

It is likely that polling the threads of this groups, or polling all threads is a better solution.

Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130