0
votes

I have currently a problem with GPars, i would like to start about 30 thread but i want to wait 1second after each thread start.

My code currently looks something like this (Groovy/Grails):

withPool(30) {    // <= thread pool size
   Mail.findAllByStatus("new").eachWithIndexParallel { mail, i ->    // <= finds about 5000 mails
      sleep(i*1000)
      def doSomething = new Test()
      doSomething.do(mail) // <= runs for about 60sec
   }
}

The problem on this solution is that "eachWithIndexParallel" starts all threads in a random order simultaneously, so for example with 5000 mails:
start thread 3500 = wait 3500 seconds
start thread 1000 = wait 1000 seconds
....until 30 threads are started then it wait for threads to stop

And i need a solution like this:
start thread 2500 = wait 1 sec
start thread 5 = wait 2 sec
start thread 4888 = wait 3 sec
...until 30 threads are started then it wait for threads to stop

If i just use a count variable then i have the problem that multiply threads have the same count number because of the simultaneously start...and its really important that i have a 1sec delay between each thread.

How can i solve this problem?

2

2 Answers

1
votes

Hmmm, I'm not a GPars expert, but I don't think this is a GPars problem. How about creating a synchronized function that the threads all call to find out what their delay is?

private static delaycount = 1;
public synchronized int getMyDelay() {
   return delaycount++;
}

And change your code to read:

int mydelay = getMyDelay()
sleep(mydelay*1000)
def doSomething = new Test()
doSomething.do(mail) // <= runs for about 60sec

inside the Mail.find....

0
votes

or use of the atomic integers

definitely if the delay is important, don't rely on the value of index, i which really should be used in enumerating the threads

i also don't think the 30 threads will stop and wait for each other new threads will keep spawning as long as n<30,

this probably defeats the benefits of having 30 threads, with 1...30 s delays

to force this anyway you might want a queue that will hold the next require delay such that whichever thread frees up will fetch the delay x from the unused numbers in 1..30