Monitoring multiple threads using Executor

John Lukar
2012-03-21
2013-05-20
  • John Lukar

    John Lukar - 2012-03-21

    Hi, I have a producer/worker scheme where a ExecutorServier.execute( new MyRunnableJob())  is used with a thread pool of 4 to launch jobs out of a thread pool.

    In my Runnable .run()  I have my monitor using the same label  e.g. "job-execution"

    I don't have access to the Thread names so that I could label each monitor on per thread basis so I fear my stats are skewed.  I am assuming that if I am using the same label across all the threads, then I am not properly measuring start/stop times on each job.

    Am I correct in this assumption ?   i.e. if one threads starts monitoring and another concurrent threads calls stop on the same label.. doesn't that mess up the aggregate stats in JAMon ?

    Help if I don't undrestand this correclty please.

    J.

     
  • Steve Souza

    Steve Souza - 2012-03-22

    If you use the same label across threads you will measure total job aggregates for all threads.  If you also want to measure each Threads time you could put a static counter in the MyRunnableJob class and increment it each time you create a new instance.  You can use this identifier in each of the instances monitor string.

     
  • John Lukar

    John Lukar - 2012-03-26

    Thank you very much Steve for the feedback !

    I think it would be fine to get the aggregate for all threads. My concern is that the way I have created a wrapper around the JAMon API could create the scenario where one thread could stop the timer for another thread.  I guess I am using the same monitor the way I am using it below:

                    
                    MonitorUtil.start("job-execution");
                    // execute the job
                    // blah blah
                    //stop the timer
                    MonitorUtil.stop(job.getType() + "-job");
    

    My MonitorUtil  is a wrapper around the JAMon API:

      

    public static Monitor start(String key) {
            Monitor mon = null;
            if (keymap.containsKey(key)) {
                mon = keymap.get(key);
                mon.start();
            } else {
                mon = MonitorFactory.start(key);
                keymap.put(key, mon);
            }
            return mon;
        }
    

    Do I need to use the full API like this to ensure one thread does not stop the timer for another thread:

                    //start
                    Monitor monitor = MonitorUtil.start(job.getType() + "-job");
                    // execute the job
                    // blah blah 
                    //stop the timer
                    monitor.stop();
    

    thank you in advance for any information
    J.

     
  • John Lukar

    John Lukar - 2012-03-26

    Sorry I meant to say in the first code snippet:

                    
                    MonitorUtil.start("job-execution");
                    // execute the job
                    // blah blah
                    //stop the timer
                    MonitorUtil.stop("job-execution");
    
     
  • Steve Souza

    Steve Souza - 2012-03-26

    You logic won't work as you are always pulling the same monitor out.

    You could do one of these 2 solutions. 

    1) Whatever your thread or job that is running could have a start when the job starts and a stop in the code where it stops.  i.e. the monitor would be an instance variable.
    2) Assign a monitor to a ThreadLocal variable.   This would allow each thread to uniquely own a monitor also.

     
  • John Lukar

    John Lukar - 2012-03-27

    Thank you Steve!
    Forgoing the desire to wrap JAMon in my own apis' and opting for using MontiorFactory directory would the below solution also result in the same monitor for the same label  ?  I am trying to piggy back on the thread safety of JAMon and I guess I am bit confused what that means.  I thought it would mean that multiple threads "creating" monitors  will each operate on that monitor without having to worry about another thread  stopping their monitor  in between.   I'd really appreciate any feedback there.  

                    //start
                    Monitor monitor =  MonitorFactory.start("job-execution");
                    // execute the job
                    // blah blah 
                    //stop the timer
                    monitor.stop();
    
     
  • Steve Souza

    Steve Souza - 2012-03-28

    All monitors with the same label store their data in the same counters.  Thread safety means that each of them can store their data in an atomic manner. 

    However, it does not mean that everyone can use the same monitor instance returned from the factor. Each monitor returned from the monitorfactory returns a monitor that can time this invocation.  But these numbers are later saved in a shared threadsafe place in jamon that aggregates data from all monitors.

     
  • John Lukar

    John Lukar - 2012-03-28

    Thank you Steve. That clears things up for me considerably.

     
  • Anonymous - 2013-03-07

    I'm asking the same question, how to monitor correctly with the same Monitor instance the same operation in different threads ?

    On my side I has created a custom class which returns an id at start, and I provide this same id when stopping.

    Thank you !

    Axel MAMONT

     
  • Steve Souza

    Steve Souza - 2013-03-07

    what you are asking isn't clear to me. give a specific example

     
  • Axel MAUMONT

    Axel MAUMONT - 2013-03-07

    Thank you for your quick answer!

    At first I wrote the following:

           

    final Monitor myMonitorTest = MonitorFactory.getTimeMonitor(tracerId);
            Runnable command = new Runnable() {
                @Override
                public void run() {
                        myMonitorTest.start();
                       // operation to mesure
                        myMonitorTest.stop();
                }
            };
            for (int i = 0; i < executionsCount; i++) {
                threadPool.execute(command);
            }
            log.info("getAvg=" + myMonitorTest.getAvg());
    

    I found that the measure is correct like that :

            Runnable command = new Runnable() {
                @Override
                public void run() {
                        Monitor myMonitorTest = MonitorFactory.start(tracerId);
                       // operations to mesure
                        myMonitorTest.stop();
                }
            };
            for (int i = 0; i < executionsCount; i++) {
                threadPool.execute(command);
            }
            final Monitor myMonitorTest = MonitorFactory.getTimeMonitor(tracerId);
            log.info("getAvg=" + myMonitorTest.getAvg());
    

    Sorry to have disturbed you :-)

    Axel MAUMONT

     
  • Steve Souza

    Steve Souza - 2013-03-07

    Thanks for posting the code.  That will help others too.  Your second example looks correct.

     

Log in to post a comment.

Get latest updates about Open Source Projects, Conferences and News.

Sign up for the SourceForge newsletter:

JavaScript is required for this form.





No, thanks