2010-11-13 13 views
7

Piszę program wielowątkowy w języku Java. Pisałem coś w tymOdrzucony wyjątek wyjątku w wątkach Java

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

Problem jestem stoi to, że tablica zostanie wydrukowany daje poprawny wynik, ale potem odrzucił Wykonanie Wyjątek pochodzi Nie rozumiem dlaczego kiedy gwinty zostały przetworzone i biorąc pod uwagę poprawne wyjście, dlaczego błąd nadchodzi ...

+1

RejectedExecutionException jest wyrzucany „, gdy zadanie nie może być przyjęte do realizacji. " Możliwe, że masz prosty błąd w sterowaniu, więc proponuję pokazać nam jakiś kod. –

+0

Ponadto, jakiej konkretnej implementacji 'Executora' używasz? –

Odpowiedz

13

Myślę, że zamykasz swojego executora zbyt wcześnie. To jest przykład, jak myślę, że powinieneś pracować.

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)); 
    } 
} 

Należy również pamiętać, że działa na tej samej tablicy w tym samym czasie może spowodować niespójność - musisz być pewien, że nie robią pracę na tablicy, która jest uzależniona od tablicy.

+3

ExecutorService.shutdown() nie czeka na zamknięcie zadań, po prostu mówi ExecutorService, aby nie akceptował kolejnych zadań i zakończył działanie. Polecenie ExecutorService.awaitTermination() powinno zostać wywołane po wywołaniu funkcji shutdown(), aby zablokować wątek wywołujący, dopóki zadania nie zostaną zakończone. – Rich

+0

Dobra uwaga! Zaktualizowany – dacwe

+0

Wierzę, że pętla while nie jest konieczna, ponieważ blokuje się sam "executor.awaitTermination" (?) – IHeartAndroid

0

Jeszcze jedna opcja może być dostać przyszłość po przesłaniu do egzekutora, a następnie zablokować na przyszłość poprzez wywołanie dostać

6

Problemem jest nadal składanie nowych zadań nawet po wywołaniu shutdown(). Używanie executor.awaitTermination() nie pomoże.

Aby rozwiązać problem, sprawdź, czy executor wheather nie jest wyłączany w momencie przesyłania zadania.

przykład:

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

Nadzieja to pomaga ...

+0

W moim przypadku executor został zamknięty dokładnie między liniami if i execute. Więc jeśli jest zaangażowany współbieżność, musisz umieścić wywołania execute() i shutdown() w zsynchronizowanych blokach/metodach. –

2

Kiedyś wyłączenia wykonawców utworzone w hak zamykania Runtime

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

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

     }); 
Powiązane problemy