Adding threads to ThreadPool in the Executor service

I am working on a multithreading program in which I try to make sure that each thread works for 30 minutes . Suppose that if there are 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 mean that each thread starts at the same time and works for 30 minutes ? I'm not sure how long it will take to put a thread in a thread pool . But it seems that it is possible that some of the threads will start to be a little late, and they will not work exactly 30 minutes , maybe less than 30 minutes.

I am looking for every thread that should start at the same time, and they should run exactly 30 minutes

+4
source share
3 answers

Short answer : No, all threads will not start at exactly the same time (depending on your tolerance, this may be "pretty" slightly). And depending on the fact that something makes sense, there is very little chance that each thread runs for exactly 30 minutes (again, your temporary granularity may make this statement incorrect).

References :

  • To maximize your chances, so that all threads start as close to each other as possible, first create your own threads, and then send them to the artist. Creating a theme in Java, like in other languages, is an expensive operation.
  • In order for the threads to run exactly 30 minutes, I would recommend that each thread calculate its completion time, since the argument that you are passing to the constructor at the moment can already affect your accuracy (due to the time the thread was created).
  • It is usually not recommended (except that you run java on a monster machine or calculus grid) to create a thread pool with 1000 threads. Keep in mind that if there are not as many cores as threads on a physical computer, a context switch will occur every 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); } } 
+1
source

At first glance, this looks like a somewhat unrealistic multi-threaded project. But you say that I am working on a multithreading program that assumes that it has a real application.

If this is the case: do not create 1000 threads just because you can. Instead, say what you really want to achieve.

About your requirements: To start all threads almost simultaneously with minimal delay, you can prestartAllCoreThreads from ThreadPoolExecutor . Send Runnables that have // do something meaningful in their launch method. To limit the execution time to 30 minutes, schedule a TimerTask, which after 30 minutes terminates ThreadPoolExecutor with shutdownNow. When creating a ThreadPoolExecutor, you can use a BlockingQueue of a fixed size with a size in the order of the desired number of threads to avoid too many tasks.

0
source

Consider using a countdown latch to maximize parallelism. Basically, you can create a singleton / static countdownLatch with a total of 1 and let multiple threads wait for the same countdown. check below what i did

The main thread that defines the start time of the stream.

 package mylab.threads; import java.util.TimerTask; import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class MainThread extends TimerTask { private static CountDownLatch countDown = new CountDownLatch(1); private ExecutorService es = Executors.newCachedThreadPool(); @Override public void run() { try { Thread1 thread1 = new Thread1(); thread1.setDoneSignal(countDown); es.submit(thread1); Thread2 thread2 = new Thread2(); thread2.setDoneSignal(countDown); es.submit(thread2); System.out.println("waiting main.. "); synchronized(this) { this.wait(2000); } System.out.println("kick off threads.."); countDown.countDown(); } catch (InterruptedException e) { e.printStackTrace(); } } } 

Identify the threads you want to run in parallel

 package mylab.threads; import java.util.Date; import java.util.TimerTask; import java.util.concurrent.CountDownLatch; public class Thread1 extends TimerTask{ private CountDownLatch doneSignal = null; /** * @return the doneSignal */ public CountDownLatch getDoneSignal() { return doneSignal; } /** * @param doneSignal the doneSignal to set */ public void setDoneSignal(CountDownLatch doneSignal) { this.doneSignal = doneSignal; } @Override public void run() { try { this.doneSignal.await(); System.out.println("get going thread 1 -"+new Date().getTime()); synchronized(this) { this.wait(3000); } System.out.println("Exiting thread 1 - "+new Date().getTime()); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } package mylab.threads; import java.util.Date; import java.util.TimerTask; import java.util.concurrent.CountDownLatch; public class Thread2 extends TimerTask{ private CountDownLatch doneSignal = null; /** * @return the doneSignal */ public CountDownLatch getDoneSignal() { return doneSignal; } /** * @param doneSignal the doneSignal to set */ public void setDoneSignal(CountDownLatch doneSignal) { this.doneSignal = doneSignal; } @Override public void run() { try { this.doneSignal.await(); System.out.println("get going thread 2 -"+new Date().getTime()); synchronized(this) { this.wait(3000); } System.out.println("Exiting thread 2 - "+new Date().getTime()); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } 

Finally, start the main thread.

 package mylab.threads; public class ThreadTest { /** * @param args */ public static void main(String[] args) { MainThread mt = new MainThread(); mt.run(); } } 

Here is the conclusion

 waiting main.. kick off threads.. get going thread 1 -1387513662107 get going thread 2 -1387513662107 Exiting thread 1 - 1387513665108 Exiting thread 2 - 1387513665108 
0
source

All Articles