Reputation: 2086
I am trying to execute 5 threads start perfectly at same time. But looking at output of below I think they started at same time but not concurrently as the age counter always finish with 5 count. If they executed real concurrently the age output must be same for the bunch. By real concurrently Or perfect Same time I think all 5 threads passing 1 as age and all thread prints same age not increment values. Please correct me.
public class ExecutorServiceTester {
public static void main(String args[]) throws InterruptedException {
ExecutorServiceTester tester = new ExecutorServiceTester();
tester.executeTester();
}
private void executeTester() throws InterruptedException {
ExecutorService executorService = Executors.newFixedThreadPool(10);
Runnable worker = new MyRunnable(1);
for (int i = 0; i < 10; i++) {
executorService.execute(worker);
} executorService.shutdown();
}
public static class MyRunnable implements Runnable {
int age = 0;
public MyRunnable(int count) {
this.age = count;
}
@Override
public void run() {
System.out.println(new Timestamp(new Date().getTime())+" ThreadName:"+Thread.currentThread().getName()
+ " Age " + age++);
}
} }
OUTPUT:
2015-03-23 02:02:18.243 ThreadName:pool-1-thread-1 Age 1
2015-03-23 02:02:18.243 ThreadName:pool-1-thread-5 Age 3
2015-03-23 02:02:18.243 ThreadName:pool-1-thread-3 Age 5
2015-03-23 02:02:18.243 ThreadName:pool-1-thread-2 Age 2
2015-03-23 02:02:18.243 ThreadName:pool-1-thread-4 Age 4
While trying with Executors.newCachedThreadPool(); and increased number to 12, the OUTPUT had something of interest then
2015-03-23 02:17:57.189 **ThreadName:pool-1-thread-4 Age 1**
2015-03-23 02:17:57.189 ThreadName:pool-1-thread-10 Age 3
2015-03-23 02:17:57.189 ThreadName:pool-1-thread-12 Age 2
2015-03-23 02:17:57.189 **ThreadName:pool-1-thread-11 Age 1** ...
Upvotes: 1
Views: 678
Reputation: 38
It may not be ideal, but if you need them to be perfectly aligned, I would set some type of Mark. Use System.nanoTime() to get a current time down to the nanosecond. Give it a period of time to wait, say a full second (1_000_000_000) nano seconds. Make sure the delay is long enough (whatever it is) for all threads to be initialized and get to waiting point. Pass that MarkTime to each thread on creation. Then have each thread have a function like this:
while(System.nanoTime() < MarkTime){
// do nothing
}
Boom, when time is reached, all threads are off and running, coordinated down to the nanosecond.
Is like runners getting ready at the starting line for a race. They all arrive at the line at different times, but all start at the same starters pistol shot.
Also, as @Keppil said, you probably want to create a new instance of the thread for each version, not 5 copies of the same instance. That way you can be sure they run independently, yet at the same time.
Alternatively: Another way to do so, is to set a boolean in the parent class, set it to false, after all threads are active, have them check that boolean. When all are loaded and running, change boolean to true. Same effect, but maybe with a slight drop in precision. How close do you need it?
Upvotes: 0
Reputation: 46209
The reason all your threads are using the same counter is that you are feeding them the same Runnable
instance. Just create a new one for each thread inside the loop instead:
for (int i = 0; i < 10; i++) {
Runnable worker = new MyRunnable(1);
executorService.execute(worker);
}
Upvotes: 1