2010-11-13 2 views
7

Я пишу многопоточную программу в java. Я написал что-то вроде этогоRejectedExecutionException в потоках Java

exec.execute(p) // where p is a runnable task working on an array 
print array 
exec.shutdown 

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

+1

RejectedExecutionException брошен «, когда задача не может быть принят к исполнению." Возможно, у вас есть простая ошибка в потоке управления, поэтому я предлагаю вам показать нам какой-то код. –

+0

Кроме того, какую конкретную реализацию «Исполнителя» вы используете? –

ответ

13

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

public class Main { 
    public static void main(String[] args) throws Exception { 

     // the array to modify 
     final int[] array = new int[1000]; 

     // start the executor (that modifies the array) 
     ExecutorService executor = Executors.newFixedThreadPool(10); 

     for (int i = 0; i < 1000; i++) { 
      final int c = i; 
      executor.execute(new Runnable() { 
       @Override 
       public void run() { 
        array[c] = c; 
       } 
      }); 
     } 

     // wait for all tasks to quit 
     executor.shutdown(); 
     while (!executor.awaitTermination(10, TimeUnit.SECONDS)); 

     // print the array 
     System.out.println(Arrays.toString(array)); 
    } 
} 

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

+3

ExecutorService.shutdown() не дождался завершения задач, он просто сообщает ExecutorService не принимать больше задач и прекращать работу. ExecutorService.awaitTermination() следует вызывать после вызова shutdown(), чтобы заблокировать вызывающий поток до завершения задач. – Rich

+0

Хорошая точка! Обновлено – dacwe

+0

Я считаю, что цикл while не нужен, поскольку блок «executor.awaitTermination» (?) – IHeartAndroid

0

Одним из вариантов может быть получить в будущем, когда вы предоставляете исполнителю, а затем блокировать на будущее по телефону получить

6

Проблема в том, вы все еще представляя новые задачи даже после вызова shutdown(). Поэтому использование executor.awaitTermination() не поможет.

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

пример:

if (!executor.isShutdown()) 
{ 
    executor.execute(new Runnable() { 
         @Override 
         public void run() { 
           array[c] = c; 
         } 
        }); 
} 

Надеется, что это помогает ...

+0

В моем случае исполнитель был закрыт точно между строками if и execute. Поэтому, если есть параллелизм, вам нужно поместить вызовы execute() и shutdown() в синхронизированные блоки/методы. –

2

Я использовал для завершения работы исполнителей, созданных во время выполнения останова крюка

Runtime.getRuntime().addShutdownHook(new Thread() { 

      public void run() { 
      if(!eExecutor.isShutdown()) { 
       eExecutor.shutdown(); 
       // await termination code 
       } 
      } 

     }); 
Смежные вопросы