开发者

Java multi-threading - what is the best way to monitor the activity of a number of threads?

I have a number of threads that are performing a long runing task. These threads themselves have child threads that do further subdi开发者_高级运维visions of work. What is the best way for me to track the following:

  • How many total threads my process has created
  • What the state of each thread currently is
  • What part of my process each thread has currently got to

I want to do it in as efficient a way as possible and once threads finish, I don't want any references to them hanging around becasuse I need to be freeing up memory as early as possible.

Any advice?


Don't think in terms of threads, which are OS objects and carry no application semantics, but in terms of tasks. A Thread cannot know it is 50% complete, a task can. Look at the facilities in java.util.concurrent for managing tasks in terms of executors and callable objects.

In most cases where you're using Java (i.e. non-embedded systems) you should not care how many threads your process has created any more (or any less) than how many objects it has created - you don't want to run out, but if you are explicitly managing OS resources in a high-level language you're probably working at the wrong level of abstraction.

For intermediate feedback, create a progress listener interface containing a method for informing the listener where the task has got to, pass it to the task on creation and call it during your task when the progress changes. Make sure any implementation of the interface is thread safe.


It seems that the information you are looking for is mostly app specific ("what part of my process each thread currently does?"). Even, "how many total threads my process has created" is app specific because you are not interested in all sort of threads that the JVM has created (GUI, GC, etc.).

Thus, the best course of action is to create your dedicated subclass of Thread. What the thread start/finish processing a job your class will register the necessary details with some central registry.

[EDIT]

Here's a typical implementation (can be refined further):

public class MyThread extends Thread 
{
   private Runnable runnable; 
   private String description;
   private Registry reg;

   public MyThread(Runnable runnable, String description, Registry reg) { 
     this.runnable = runnable; 
     this.description = description;
     this.reg = reg; 
   }


   public void run() {
      int id = reg.jobStarting(description); 
      try {
         runnable.run();
         reg.jobEnded(id);
      }
      catch(Throwable t) {
        reg.jobFailed(id, t);
      }
   }
}


Use JMX: http://java.sun.com/j2se/1.5.0/docs/guide/management/agent.html

Add the following parameters to your jvm (after javac ...):

-Dcom.sun.management.jmxremote.port=8086 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false

Then connect using jconsole. JConsole will be in the bin folder of your JDK. I am sure it comes with the JDK but i'm not sure if it's bundled with the JRE. In this case, when JConsole pop's up, enter localhost:8086 as the ip address. Change the port if needed.

In JConsole, click on the Thread tab. This will show you the number of running and started threads with a nice graph. You can also click on the thread to see the current stack trace. You even have a button to detect dead locks!


I would change the design approach altogether and reason with Work instead of Threads.

You chunk your big task into work that you submit to executors/worker (see also the thread pool pattern). Then you can register listener that get notified when a work is started/completed/aborted.

The JCA specification implement this pattern in the WorkManager, you can draw some inspiration from it:

void scheduleWork(Work work, 
                  long startTimeout, 
                  ExecutionContext execContext, 
                  WorkListener workListener) 

And the listener

 void workAccepted(WorkEvent e);
 void workCompleted(WorkEvent e);
 void workRejected(WorkEvent e);
 void workStarted(WorkEvent e);

Otherwise have a look at the java.util.concurrent there is also some interesting stuff in it.


Use Visual VM from sun/oracle, free tool. Pretty good tool, gives you lot of details about threads, memory used, cpu for the process running.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜