1

This is a simplification of my code:

for(int i = 0; i < 500; i++) {
    someMethod(i);
}

someMethod() takes a long time to execute, so I want to use multithreading to break up the for-loop into 5 intervals of 100:

for(int i = 0; i < 100; i++) {
    someMethod(i);
}

for(int i = 100; i < 200; i++) {
    someMethod(i);
}

...

for(int i = 400; i < 500; i++) {
    someMethod(i);
}

so I can execute someMethod() concurrently for different i.

How do I use multithreading to accomplish this?

Please help! Thanks!

Jessica Myers
  • 35
  • 1
  • 6

1 Answers1

9

It is recommended to use the great ExecutorService code for situations like this. What you do is submit all of your tasks (0 to 499) into the thread pool and they will be run concurrently by the 5 threads in the pool.

Something like the following:

// create a thread pool with 5 workers
ExecutorService threadPool = Executors.newFixedThreadPool(5);
// submit all of your jobs here
for (int i = 0; i < 500; i++) {
    threadPool.submit(new MyJob(i));
}
// once we have submitted all jobs to the thread pool, it should be shutdown
threadPool.shutdown();
// if you need to wait for the pool you can do
threadPool.awaitTerminatation(Long.MAX_VALUE, TimeUnit.MILLISECONDS);

private static class MyJob implements Runnable {
   private int i;
   public MyJob(int i) {
       this.i = i;
   }
   public void run() {
       // do the thread stuff here
   }
}
Eng.Fouad
  • 115,165
  • 71
  • 313
  • 417
Gray
  • 115,027
  • 24
  • 293
  • 354
  • By `// do the thread stuff here`, what do you mean? Also, where does `someMethod()` factor into this? – Jessica Myers Jul 26 '12 at 21:00
  • 1
    So @Jessica, you can copy what is in `someMethod()` and put that code into `run()`. You could also pass in the class that forks the thread into the `MyJob` constructor and then inside of run do: `caller.someMethod(i)`. Your choice. – Gray Jul 26 '12 at 21:03
  • 1
    just replace `// do the thread stuff here` with `someMethod(i);` :) .. +1 for Gray – Eng.Fouad Jul 26 '12 at 21:04
  • One more question, if anyone is still around: I have a `boolean done = false` at the beginning of my code. One of those `i` values will toggle `done`. I want to stop the for-loop when that happens. Right now I added `if(done) return;` to `run()` but all the `someMethod()`s that have already started need to `return;` so there's a short time delay. What's a better way to do this? – Jessica Myers Jul 26 '12 at 22:15
  • That's harder because the jobs have already been submitted to the thread-pool. You could make `done` be volatile and just put a `if (done) return;` the first thing in the `run()` method @Jessica. – Gray Jul 26 '12 at 22:44
  • @JessicaMyers maybe you could interrupt all other thread using Thread.interrupt(). For more explanation, see http://stackoverflow.com/questions/1680525/how-do-i-kill-a-thread-from-another-thread-in-java – Riza Jul 26 '12 at 23:20