여기 가짜 개체가 있습니다. "다운로드"무작위 잠 있습니다 : 우리는 파일을 다운로드하는 작업을 정의 할 수 있습니다
// for illustration only
class S3Object {
String id;
}
// for illustration only
class S3Downloader {
public S3Object download(String url) {
int min = 2;
int max = 5;
Random rand = new Random();
int random = rand.nextInt((max - min) + 1) + min;
try { Thread.sleep(1000 * random); } catch (Exception ex) {}
S3Object result = new S3Object();
result.id = url;
return result;
}
}
이하는 (thread에 대해서 안전한)리스트를 업데이트하고,
CountDownLatch
감소 :
이
class MyTask implements Runnable {
private final List<S3Object> list;
private final CountDownLatch latch;
private final String url;
public MyTask(List<S3Object> list, CountDownLatch latch, String url) {
this.list = list;
this.latch = latch;
this.url = url;
}
public void run() {
S3Downloader downloader = new S3Downloader();
S3Object result = downloader.download(url);
list.add(result);
latch.countDown();
}
}
예 러너가 보여 "클라이언트". go
방법은 드라이버, 그리고 (차단하지 않는)을 add
방법을 사용 가능하게 오류를 처리해야
public class Runner {
private ExecutorService pool = Executors.newCachedThreadPool();
private int numUrls = 20;
private CountDownLatch latch = new CountDownLatch(numUrls);
private List<S3Object> results = Collections.synchronizedList(new ArrayList<S3Object>());
public void add(String url) {
pool.submit(new MyTask(results, latch, url));
}
public void go() throws Exception {
for(int i = 0; i < numUrls; i++) {
String url = "http://example" + i;
add(url);
}
// wait for all downloads
latch.await();
for (S3Object result : results) {
System.out.println("result id: " + result.id);
}
}
}
생산 코드가 적절한 클라이언트를 재구성.
이미 '미래'가있는 경우 추가로 '호출 가능'이란 이점은 무엇입니까? – Kayaman
@Kayaman, 제 생각에'Future'의'get()'메소드를 호출하면'add' 메소드가 차단 될 것입니다. 그것이 내가 새로운 Callable'FutureWatcher'를 제출 한 이유입니다. – dmux
그래서'Callable'은 어떤 역할을합니까? 그것의'call()'메소드를 호출하는 것은'get()'에 위임하기 때문에 역시 차단 될 것이다. – Kayaman