2017-11-23 5 views
0

CountDownLatch를 사용하여 일부 코드를 실행하기 전에 N 작업이 완료 될 때까지 기다리는 동안 시간 제한을 사용하여 모든 N 작업이 완료되지는 않더라도 최종 코드가 실행되도록합니다. 예 :동적 타임 아웃이있는 CountDownLatch

CountDownLatch latch= new CountDownLatch(N); 
    latch.await(20, TimeUnit.MINUTES); 
    //Some code 

나는 그것이 래치가 카운트 다운을 얻을 때마다 리셋되도록 동적으로 20 분 타임 아웃을하고 싶은, 그래서 래치이 (가) 20 분 마지막 경과 한 경우에만 기다리고 종료됩니다 시간은 카운트 다운 (또는 N 카운트 다운을받는 보통의 경우)입니다. 이것은 어떤 방식 으로든 지원됩니까?

답변

0

이 기능은 사용자 본인의 CountDownLatch에서 구현할 수 있습니다. countDown() 메서드가 호출 될 때의 타임 스탬프를 유지하고 대기가 시작된 타임 스탬프와 비교하여 대기 시간을 조정하고 타임 스탬프가 다른 경우 다시 기다릴 수 있습니다.

import java.time.LocalTime; 
import java.util.Arrays; 
import java.util.List; 
import java.util.concurrent.CountDownLatch; 
import java.util.concurrent.TimeUnit; 

public class Test { 

    public static void main(String[] args) throws InterruptedException { 

     MyCountDownLatch latch = new MyCountDownLatch(3); 

     // Create three workers and give them different work time 
     Worker worker1 = new Worker("A", 1, latch); 
     Worker worker2 = new Worker("B", 3, latch); 
     Worker worker3 = new Worker("C", 5, latch); 
     List<Worker> workers = Arrays.asList(worker1, worker2, worker3); 

     // Start the workers 
     workers.forEach(Worker::start); 

     // Wait until the latch to count down to zero, or no countdown in 
     // 3 seconds. 
     boolean result = latch.waitFor(3, TimeUnit.SECONDS); 
     System.out.printf("%s | latch.waitFor() returns %b\n", LocalTime.now(), result); 

     // Terminate those workers who are still running 
     workers.stream().filter(Worker::isAlive).forEach(Worker::interrupt); 
    } 


    static class Worker extends Thread { 
     private String name; 
     private int workTime; 
     private CountDownLatch latch; 

     public Worker(String name, int workTime, CountDownLatch latch) { 
      this.name = name; 
      this.workTime = workTime; 
      this.latch = latch; 
     } 

     @Override 
     public void run() { 
      try { 
       System.out.printf("%s | Worker %s started\n", LocalTime.now(), name); 
       Thread.sleep(workTime * 1000L); 
       System.out.printf("%s | Worker %s finished\n", LocalTime.now(), name); 
      } catch (InterruptedException e) { 
       System.out.printf("%s | Worker %s interrupted\n", LocalTime.now(), name); 
      } finally { 
       latch.countDown(); 
      } 
     } 
    } 
} 
: 예를 들어, 다음
import java.util.concurrent.CountDownLatch; 
import java.util.concurrent.TimeUnit; 
import java.util.concurrent.atomic.AtomicLong; 

public class MyCountDownLatch extends CountDownLatch { 
    private AtomicLong timestamp; 

    public MyCountDownLatch(int count) { 
     super(count); 
     timestamp = new AtomicLong(System.nanoTime()); 
    } 

    @Override 
    public void countDown() { 
     super.countDown(); 
     timestamp.set(System.nanoTime()); 
    } 

    public boolean waitFor(long timeout, TimeUnit unit) throws InterruptedException { 
     long start = timestamp.get(); 
     long diff = 0; 
     for (;;) { 
      boolean result = await(unit.toNanos(timeout) - diff, TimeUnit.NANOSECONDS); 
      if (timestamp.get() == start) return result; 
      start = timestamp.get(); 
      diff = System.nanoTime() - start; 
     } 
    } 
} 

그리고

테스트 프로그램입니다
관련 문제