2016-07-22 2 views
-1

Я хочу одновременно запустить два ExecutorService.Запуск нескольких ExecutorService Java

Например, в моей основной:

MyClass.firstAsync(); 
MyClass.secondAsync(); 

и

public void firstAsync() { 
ExecutorService service = Executors.newFixedThreadPool(4); 
    service.submit(new Runnable() { 
     public void run() { 
      while (true) { 
       System.out.println("I m running : First Async"); 
     } 
    }); 
} 

затем

public void secondAsync() { 
    ExecutorService service = Executors.newFixedThreadPool(4); 
     service.submit(new Runnable() { 
      public void run() { 
      while (true) { 
       System.out.println("I m running : Second Async"); 
       } 
     }); 
    } 

Проблема: когда называется второй класс, он занимает место первого. Поэтому у меня есть этот выход:

I m running : First Async 

в то время как второй ExecutorService is'nt запущен, но у меня есть этот выход

I m running : Second Async 

, когда вторая запускается.

Я также попытался поставить их на ту же услугу (есть два service.submit (...) на одной и той же ExecutorService), но он не работает на всех

То, что я хочу оба выхода , в то же время".

Благодарим вас, Clément.

+0

Зачем вам в первую очередь нужны два отдельных пула потоков? – TMichelsen

+3

Я не понимаю ваш вопрос; ни проблема, которая может быть за вашей идеей/запросом. – GhostCat

+0

Моя программа такая. Первая функция не делает то же самое, что и второе (в моем реальном ключе) – Souin

ответ

1

Вы не можете рассчитывать контролировать выполнение потоков. Если вы хотите, чтобы имитировать его, давайте познакомимся в ваших петлях:

Thread.sleep(10); 

Это заставляет ток, протекающую тему сна, и дает шанс другим потокам для выполнения.

Но не ожидайте, чтобы организовать выполнение потока.

+0

Хорошо. Но мои две функции, в реале, слушают серверную информацию. Поэтому мне нужно, чтобы обе функции знали о том, что сервер хочет сказать. Проблема в том, что первая функция имеет статус блокировки, а вторая тоже. Поэтому мне нужно отделить эти функции, и мне нужно, чтобы эти функции запускались каждый раз, не блокируя другую функцию. – Souin

+0

Клемент, у вас есть только один ядро ​​на вашей машине? В противном случае, когда вы запускаете разные потоки, они оба запускаются одновременно. –

1

Ваш код работает должным образом. Я предполагаю, что вы ожидали получить такой результат:

I m running : First Async 
I m running : Second Async 
I m running : First Async 
I m running : Second Async 

Но вместо этого вы получаете:

I m running : First Async 
I m running : First Async 
... 
I m running : First Async 
I m running : Second Async 
I m running : Second Async 
... 
I m running : Second Async 
I m running : First Async 
... 
I m running : First Async 
I m running : Second Async 
... 
I m running : Second Async 

А может быть, вы получаете так много выход из одного потока, что вы не видите выход из другой.

Это происходит потому, что оба потока конкурируют за доступ к одному и тому же выходному потоку (System.out), и каждый раз, когда у него есть доступ, ему удается распечатать несколько строк (может быть, тысячи), прежде чем другой поток получит разрешение по потоку.

Чтобы проверить это, добавьте задержку в своих циклах, чтобы каждый поток успевал печатать только одну строку за раз.

while (true) { 
    System.out.println("I m running : First Async"); 
    Thread.sleep(100); // <---- and surround with try-catch 
} 
while (true) { 
    System.out.println("I m running : Second Async"); 
    Thread.sleep(100); // <---- and surround with try-catch 
} 
+0

Это не моя проблема. Моя проблема: при запуске второй асинхронной функции первая закрывается, как по волшебству! – Souin

+0

@ ClémentB Если первый из них действительно закрыт, и вы не ошибаетесь в интерпретации вывода, тогда код, который вы отправили, не включает проблему, вызывающую это. Попробуйте использовать задержки и если они не работают, добавьте еще код –

+0

Пробовал ли вы отлаживать свой код с помощью контрольных точек? –

0

(1) Ваш код в порядке (за исключением некоторых незначительных замечаний ниже), проблема в том, что просто фактический код слишком быстро, чтобы заметить параллелизм! Кроме того, println обычно синхронизируется. Если вы замените каждый «run()» на некоторый цикл, который печатает несколько строк, вы заметите параллелизм.

(2) Я бы рассмотрел два исправления, независимо: (a) Вам действительно нужны 2 отдельных пула потоков? Это нормально, если вы это делаете, просто причина не ясна из примера. (B) Я не вижу большого смысла в создании пула потоков в качестве локальной переменной метода, его следует разместить там, где он может быть повторно использован + контролируется + завершается когда-то. Очевидно, вы, возможно, просто упростили код для обсуждения ...

+0

Я также пробовал на том же ExecutorService, но он тоже не работает:/ – Souin

+1

Я действительно скопировал и запустил код (как есть, без моих предлагаемых изменений в управление исполнителем). Я просто изменил сингл «println» в цикл из 100 «println» ... и он работал отлично, получая смешанный вывод. Вы на самом деле пытались это сделать? Как я уже упоминал, вы не увидите параллелизма с одним «println» .... –

+0

@ Посмотрите мой окончательный ответ :) Спасибо. – Souin

0

Я хотел бы сделать комментарий, но, видимо, мне нужно 50 репутации на stackoverflow, чтобы прокомментировать (резонирующий, но неудачный.). Поэтому я попытаюсь ответить на этот вопрос.

ExecutorService предназначен для управления объектом, который реализует интерфейс Executor, это означает, что он может содержать в нем threadpool. Пул потоков может использоваться для размещения разнообразных объектов Runnable thread. Они не должны быть одного типа.

Так, например, если у вас был класс Runable с определенной функцией, вы можете запустить это из потока, хранящегося в ExecutorService, потому что потоки являются общими. Если вам требуется идентифицировать конкретные потоки для взаимодействия с ними позже, вы можете иметь определенное поле неизменяемого идентификатора класса с методом getter в каждом типе типа Runnable. Или, если хотите, вы можете сохранить ссылку на объект потока при его создании.

В качестве альтернативы существует возможность поиска текущих потоков/групп потоков и их идентификаторов. Вы можете увидеть этот метод здесь:

http://nadeausoftware.com/articles/2008/04/java_tip_how_list_and_find_threads_and_thread_groups#GettingThreadGroups

Ответ на ваш вопрос в том, что вам не нужно иметь два ExecutorServices. Поскольку вы можете размер пула потоков в статическом или динамическом режиме, и ваш threadpool может содержать объекты хетрогенной нити.

Надеюсь, это поможет. И я надеюсь, что это адекватный ответ.

+0

Хорошо, только что увидели все остальные ответы. Не могли бы вы сохранить исполнителей (если они действительно нужны) как поля классов, не сохраняя их локально в ваших методах? –

0

Вот мой окончательный ответ.

В моем коде firstAsync() появилось исключение NullPointerException, которое НИКОГДА не отображалось на консоли.

Я потратил больше часа на то, чтобы найти парня из моей службы. Это мое плохое. Ваш ответ был хорошим, и мой вопрос был глупым.

Thank's, Clément.

Смежные вопросы