Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Adding Thread in ThreadPool in Executor Service

I am working on a Multithreading Program in which I am trying to make sure each Thread is running for 30 minutes. Suppose if we have 10 threads then each thread out of 10 should run for 30 minutes.

Below is my code-

class ThreadTask implements Runnable {
    private final long endTime;

    public ThreadTask(long endTime) {
        this.endTime = endTime;
    }

    @Override
    public void run() {

        while (System.currentTimeMillis() <= endTime) {

            // do something meaningful

        }   
    }
}

public class TestPool {

    public static void main(String[] args) {

        // create thread pool with given size
        ExecutorService service = Executors.newFixedThreadPool(1000); 

        long startTime = System.currentTimeMillis();
        long endTime = startTime + (30 * 60 * 1000);

        for (int i = 0; i < threads; i++) {
            service.submit(new ThreadTask(endTime));
        }

        // wait for termination        
        service.shutdown();
        service.awaitTermination(Long.MAX_VALUE, TimeUnit.DAYS); 
    }
}

Now my question is-

Does the above code guarantee that each thread is starting at the same time and running for 30 minutes? I am not sure how much time it takes to put the thread in Thread Pool. But it looks like it might be possible that some of the thread will start little bit late and they won't be running for exactly 30 minutes, might be less than 30 minutes.

I am looking for each thread should start at same time and they should run for exactly 30 minutes

like image 259
AKIWEB Avatar asked Nov 12 '22 10:11

AKIWEB


1 Answers

Short answer: No, all the threads will not start exactly at the same time (depending on what your tolerance is, it could be 'quite' negligible). And depending on what something meaningful does, there is very little chance that each thread runs exactly 30 minutes (again here, your time granularity could make this assertion wrong).

Leads:

  • To make sure to maximize your chances that all threads start as close as possible from each other, create your threads first and then submit it to the executor. Thread creation, in Java as in other languages, is an expensive operation.
  • For the threads to run exactly 30 minutes, I would recommend that each thread computes itself its termination time since the argument your are currently passing to the constructor could already affect your precision (due to the thread creation time).
  • It is usually not recommended (except if your run java on a monster machine or a calculus grid) to create a thread pool with 1000 threads. Keep in mind that if the physical machine does not have as many cores as threads, a context switch will occur each time the JVM decides which thread should run.

EDIT:

public class TestPool {

    public static void main(String[] args) {

        // create thread pool with given size
        ExecutorService service = Executors.newFixedThreadPool(10); 

        long startTime = System.currentTimeMillis();
        long endTime = startTime + (30 * 60 * 1000);

        ThreadTask[] threadTasks = new ThreadTask[threads];
        for (int i = 0; i < threads; i++) {
            threadTasks[i] = new ThreadTask(endTime);
        }

        for (ThreadTask tt : threadTasks) {
            service.submit(tt);
        }

        // wait for termination        
        service.shutdown();
        service.awaitTermination(Long.MAX_VALUE, TimeUnit.DAYS); 
    }
}
like image 66
aymeric Avatar answered Nov 15 '22 06:11

aymeric