문제

나는 집행자를 사용하여 작업을 제출했으며 얼마 후 중지해야합니다 (예 : 5 분). 나는 다음과 같이 시도했다 :

   for (Future<?> fut : e.invokeAll(tasks, 300, TimeUnit.SECONDS)) {
         try {
             fut.get(); 
         } catch (CancellationException ex) {
             fut.cancel(true);   
             tasks.clear();
         } catch(ExecutionException ex){
             ex.printStackTrace(); //FIXME: gestita con printstack       
         }
   }

그러나 나는 항상 오류가 발생합니다. 작업에 의해 수정 해야하는 공유 벡터가 있습니다. 그런 다음 스레드에 의해 읽어야하며, 모든 작업을 중지하더라도 타임 아웃이 발생하면 다음을 얻습니다.

Exception in thread "Thread-1" java.util.ConcurrentModificationException

뭔가 잘못 되었나요? 5 분 후에도 여전히 작동중인 제출 된 작업을 중지하려면 어떻게해야합니까?

도움이 되었습니까?

해결책

당신이 전화하기 때문에 cancel() ~에 Future 작업이 자동으로 중지된다는 의미는 아닙니다. 작업 내에서 일부 작업을 수행해야합니다.

  • 사용 cancel(true) 인터럽트가 작업으로 전송됩니다.
  • 핸들 InterruptedException. 작업의 함수가 던지는 경우 InterruptedException, 예외를 잡을 때 가능한 빨리 우아하게 나가십시오.
  • 주기적으로 확인하십시오 Thread.currentThread().isInterrupted() 작업이 연속 계산을 수행하는 경우

예를 들어:

class LongTask implements Callable<Double> {
    public Double call() {

         // Sleep for a while; handle InterruptedException appropriately
         try {
             Thread.sleep(10000);
         } catch (InterruptedException ex) {
             System.out.println("Exiting gracefully!");
             return null;
         }


         // Compute for a while; check Thread.isInterrupted() periodically
         double sum = 0.0;
         for (long i = 0; i < 10000000; i++) {
             sum += 10.0
             if (Thread.currentThread().isInterrupted()) {
                 System.out.println("Exiting gracefully");
                 return null;
             }
         }

         return sum;
    } 
}

또한 다른 게시물이 언급했듯이 : ConcurrentModificationException 스레드 안전을 사용하더라도 던질 수 있습니다 Vector 수업, 반복자가 얻으므로 Vector 스레드 안전이 아니므로 동기화해야합니다. 고급 루프는 반복자를 사용하므로 다음과 같이 조심하십시오.

final Vector<Double> vector = new Vector<Double>();
vector.add(1.0);
vector.add(2.0);

// Not thread safe!  If another thread modifies "vector" during the loop, then
// a ConcurrentModificationException will be thrown.
for (Double num : vector) {
    System.out.println(num);
}

// You can try this as a quick fix, but it might not be what you want:
synchronized (vector) {    // "vector" must be final
    for (Double num : vector) {
        System.out.println(num);
    }
}

다른 팁

그만큼 ConcurrentModificationException 당신의 전화에서오고 있습니다 tasks.clear() 당신의 exceutors가 당신을 반복하는 동안 tasks Vector. 당신이 시도 할 수있는 것은 전화입니다 shutdownNow() 귀하의 ExecutorService에서

가장 일반적인 경우 ConcurrentModificationException 언제입니다 vector 반복되는 것과 동시에 수정되고 있습니다. 종종 이것은 단일 스레드에서 이루어집니다. 당신은 잠금 장치를 잡아야합니다 Vector 전체 반복을 위해 (그리고 교착 상태에도주의하지 않음).

fut.get ()는 차단 호출입니다. 타임 아웃 후에도 작업이 완료 될 때까지 차단됩니다. 가능한 5 분 마크에 가깝게 중지하려면 인터럽트 플래그를 확인해야합니다. 인터럽트 상태를 보존하는 thread.isterrupted () 메소드를 사용하는 것이 좋습니다. 즉시 멈추고 상태를 청소할 필요가 없다면 미래에 잡히고 실행 지출로 표시되는 예외를 던지십시오.

fut.cancel (true)은 invokeall () 메소드가 이미 당신을 위해 이것을 수행했기 때문에 아무것도하지 않습니다.

다른 곳에서 "작업"컬렉션을 사용하지 않으면 Clear ()를 호출 할 필요가 없습니다. invokeall () 메소드가 clear () 호출 할 때까지 목록과 함께 수행되므로 문제의 원인이되지 않습니다. 그러나 실행할 새로운 작업 목록을 작성 해야하는 경우 새 작업 목록을 사용하지 않고 새 작업 목록을 작성하는 것이 좋습니다.

불행히도, 나는 당신의 문제에 대한 답이 없습니다. 나는 여기에서 그것을 진단하기에 충분한 정보를 보지 못한다. 귀하가 제공 한 코드 스 니펫의 어떤 것도 도서관 클래스/방법의 부적절한 (불필요한) 사용을 나타냅니다. 아마도 한 줄 오류 대신 풀 스택 추적을 포함시킬 수 있습니다.

fut.cancel(true); 마침내 블록에서

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top