user1583803
user1583803

Reputation: 424

How to calculate the total time it takes for multiple threads to finish executing?

I am starting multiple threads(around 1000) from my code. They are Runnable threads called from a while loop. How do I calculate the total time taken for all threads to finish executing?

Also I am opening a DB Connection and have a set of queries for which I am starting these threads(1 thread for 1 query). When do I close the connection?

Upvotes: 5

Views: 15933

Answers (6)

Taky
Taky

Reputation: 5344

In general you cannot measure time execution exactly because context switching. If you have 1000 threads it is produce significant impact to all time measuring. Nevertheless if you may omit high exactness of time measuring you may use CountDownLautching primitive to synchronizing thread starting and thread finishing:

    public static void main( String[] args ) throws InterruptedException {
    final int THREAD_COUNT = 10000;
    long startTime;
    long endTime;
    final CountDownLatch startBarierr = new CountDownLatch(THREAD_COUNT + 1);
    final CountDownLatch finishBarierr = new CountDownLatch(THREAD_COUNT);
    for (int i = 0; i < THREAD_COUNT; i++){
        final int iterationIndex = i;
        new Thread(new Runnable() {
            @Override
            public void run() {
                startBarierr.countDown();
                System.out.println("Thread " + iterationIndex + " started");
                try {
                    startBarierr.await();
                    //do some work in separate thread
                    int iterationCount = (int)(0.8*Integer.MAX_VALUE);
                    for(int i = 0; i < iterationCount; i++){

                    }
                    System.out.println("Thread " + iterationIndex + " finished");
                    finishBarierr.countDown(); //current thread finished, send mark
                } catch (InterruptedException e) {
                    throw new AssertionError("Unexpected thread interrupting");
                }
            }
        }).start();
    }
    startBarierr.countDown();
    startBarierr.await(); //await start for all thread
    startTime = System.currentTimeMillis(); //and note time
    finishBarierr.await(); //wait each thread
    endTime = System.currentTimeMillis();   //note finish time
    System.out.println("Time(ms) - " + (endTime - startTime));
}

Upvotes: 1

Eugene
Eugene

Reputation: 120848

You need another Thread to wait until these 1000 Threads have finished their work, you can do that with a CountDownLatch, but you need to know the exact number of Threads that you have - 1000 in your case.

Something like this:

public class LatchTest {
    public static void main(String[] args) throws Exception {

        final CountDownLatch latch = new CountDownLatch(100);

        long startTime = System.nanoTime();
        for(int i=0;i<100;++i){
            new Thread(new Runnable() {
                public void run() {
                    //Simulate some work
                    latch.countDown();
            }).start();
        }

        // Main Thread will wait for all Threads to finish
        latch.await();
        long finishTime = System.nanoTime();
        System.out.println("Have passed : " + (finishTime - startTime));
    }
}

Upvotes: 1

gresdiplitude
gresdiplitude

Reputation: 1685

Use a CountDownLatch like mentioned here.

public class StopLatchedThread extends Thread {
  private final CountDownLatch stopLatch;

  public StopLatchedThread(CountDownLatch stopLatch) {
    this.stopLatch = stopLatch;
  }
  public void run() {
    try {
      // perform interesting task
    } finally {
      stopLatch.countDown();
    }
  }
}

public void performParallelTask() throws InterruptedException {
  CountDownLatch cdl = new CountDownLatch(10);
  for (int i = 0; i < 10; i++) {
    Thread t = new StopLatchedThread(cdl);
    t.start();
  }
  cdl.await();
}

Upvotes: 3

Brian Agnew
Brian Agnew

Reputation: 272257

Why not throw them all into an Executor, and call get() on each resultant Future in turn?

Once the last thread completes, then you'll have called your last get() and you can time that complete operation.

Upvotes: 1

Peter Lawrey
Peter Lawrey

Reputation: 533500

I would use an ExecutorService

long start = System.nanoTime();
ExecutorService service = Executors.newWhatEverPool();
for(loop)
   service.submit(new MyRunnable());

service.shutdown();
service.awaitTermination(1, TimeUnit.HOUR); // or longer.    
long time = System.nanoTime() - start;
System.out.printf("Tasks took %.3f ms to run%n", time/1e6);

Close the connection when you have finished with it. It is a common pattern for the creator of a resource to also close it. e.g. If the main thread creates the connection, it could close after all the threads have finished.

Upvotes: 8

jderda
jderda

Reputation: 890

Probably the easiest way is to put those Threads on a list and checking in intervals whether any of them is alive (Thread.isAlive() method), taking the dead ones off the list. Repeat until list is empty. Downside is that it'll give you the time with some error margin.

The other solution is to inject 'parent' controller into those threads, then make them report back upon finishing. The same logic applies - we can pull a finished thread from list (or some other kind of set) until our list is empty. This method is more precise, but requires adding additional logic into threads.

Upvotes: 0

Related Questions