В то же время я пытаюсь выполнить 5 потоков. Но, глядя на результат ниже, я думаю, что они начались в то же время, но не одновременно, так как счетчик возрастов всегда заканчивается на 5 счет. Если они выполняются реальным одновременно, выход возраста должен быть одинаковым для группы. По существу одновременно или идеально. В то же время я думаю, что все 5 потоков, проходящих 1 по возрасту, и все нити печатают один и тот же возраст, а не увеличивают значения. Пожалуйста, поправьте меня.
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++);
}
} }
ВЫВОД:
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
При попытке с помощью Executors.newCachedThreadPool(); и увеличенное число до 12, у OUTPUT было что-то интересное тогда
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** ...
Причина, по которой все ваши потоки используют один и тот же счетчик, заключается в том, что вы кормите их одним и тем же экземпляром Runnable
. Просто создайте новый для каждого потока внутри цикла:
for (int i = 0; i < 10; i++) {
Runnable worker = new MyRunnable(1);
executorService.execute(worker);
}
Это может быть не идеально, но если вам нужно, чтобы они были идеально выровнены, я бы поставил некоторый тип Mark. Используйте System.nanoTime(), чтобы получить текущее время до наносекунды. Дайте ему время подождать, скажем, полные секунды (1_000_000_000) nano секунд. Убедитесь, что задержка достаточно длинная (независимо от того, что она есть), чтобы все потоки были инициализированы и попали в точку ожидания. Передайте этот MarkTime каждому потоку при создании. Затем каждый поток имеет такую функцию:
while(System.nanoTime() < MarkTime){
// do nothing
}
Стрела, когда время достигнуто, все потоки отключены и работают, скоординированные до наносекунды.
Похоже, что бегуны готовятся к стартовой линии гонки. Все они приходят на линию в разное время, но все начинают с того же самого выстрела из пистолета.
Кроме того, как сказал @Keppil, вы, вероятно, хотите создать новый экземпляр потока для каждой версии, а не 5 экземпляров одного и того же экземпляра. Таким образом, вы можете быть уверены, что они работают независимо, но в то же время.
Альтернативно: Другой способ сделать это - установить логическое значение в родительском классе, установить значение false, после того как все потоки будут активны, попросите их проверить, что логическое. Когда все загружено и запущено, измените значение boolean на true. Тот же эффект, но, возможно, с небольшим снижением точности. Как близко вам это нужно?