как программа может гарантировать одновременное выполнение нескольких потоков с использованием среды executor

1

В то же время я пытаюсь выполнить 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** ...
  • 0
    Я не понимаю, что вы имеете в виду, если они выполнялись по-настоящему одновременно . Не могли бы вы объяснить более подробно, какая часть вывода вас смущает?
  • 0
    Вы печатаете имя текущего потока рядом с каждой строкой вывода, чтобы гарантировать, что эти строки не выводятся из одного потока
Показать ещё 4 комментария
Теги:
multithreading
runnable
executorservice
concurrency

2 ответа

1

Причина, по которой все ваши потоки используют один и тот же счетчик, заключается в том, что вы кормите их одним и тем же экземпляром Runnable. Просто создайте новый для каждого потока внутри цикла:

for (int i = 0; i < 10; i++) {
    Runnable worker = new MyRunnable(1);
    executorService.execute(worker);
}
  • 0
    В этом случае также потоки не выполняются одновременно. Не могли бы вы подсказать, как сделать так, чтобы все запускались и выполнялись одновременно. Хотя ваше предложение верно для счетчика, но я все еще вижу, как они выполняются в разное время с этим.
  • 0
    При попытке с Executors.newCachedThreadPool (); и увеличив число до 12, я обнаружил, что 2 темы фактически имеют одинаковый возраст (обновлен вывод моего вопроса)
Показать ещё 1 комментарий
0

Это может быть не идеально, но если вам нужно, чтобы они были идеально выровнены, я бы поставил некоторый тип Mark. Используйте System.nanoTime(), чтобы получить текущее время до наносекунды. Дайте ему время подождать, скажем, полные секунды (1_000_000_000) nano секунд. Убедитесь, что задержка достаточно длинная (независимо от того, что она есть), чтобы все потоки были инициализированы и попали в точку ожидания. Передайте этот MarkTime каждому потоку при создании. Затем каждый поток имеет такую функцию:

while(System.nanoTime() < MarkTime){
    // do nothing
}

Стрела, когда время достигнуто, все потоки отключены и работают, скоординированные до наносекунды.

Похоже, что бегуны готовятся к стартовой линии гонки. Все они приходят на линию в разное время, но все начинают с того же самого выстрела из пистолета.

Кроме того, как сказал @Keppil, вы, вероятно, хотите создать новый экземпляр потока для каждой версии, а не 5 экземпляров одного и того же экземпляра. Таким образом, вы можете быть уверены, что они работают независимо, но в то же время.

Альтернативно: Другой способ сделать это - установить логическое значение в родительском классе, установить значение false, после того как все потоки будут активны, попросите их проверить, что логическое. Когда все загружено и запущено, измените значение boolean на true. Тот же эффект, но, возможно, с небольшим снижением точности. Как близко вам это нужно?

Ещё вопросы

Сообщество Overcoder
Наверх
Меню