Tôi chỉ bắt đầu xem xét Futures và ScheduledExecutorService trong Java, và tôi tự hỏi tại sao Callable của tôi không chạy theo lịch biểu tôi đã chỉ ra. Trong mã mẫu này, các cuộc gọi chạy một lần, nhưng các ứng dụng không bao giờ hoàn thành, cũng không phải nhiệm vụ chạy một lần nữa, đó là những gì tôi dự kiến sẽ xảy ra (Tôi chắc chắn vấn đề là với kỳ vọng của tôi).Tìm kiếm rõ ràng trên Java ScheduledExecutorService và FutureTask
Runnables hoạt động tốt; Cuộc gọi dường như chặn mãi mãi, nhưng tôi không chắc tại sao .... Tôi đang thiếu gì?
Cảm ơn!
public class ExecutorExample {
/**
* @param args
* @throws ExecutionException
* @throws InterruptedException
*/
public static void main(String[] args) throws InterruptedException, ExecutionException {
ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(5);
FutureTask<ArrayList<String>> ft1 = new FutureTask<ArrayList<String>>(new Callable<ArrayList<String>>(){
@Override
public ArrayList<String> call() {
ArrayList<String> stuff = new ArrayList<String>();
for(int i = 0;i<10;i++){
String thing ="Adding " + i + " to result";
stuff.add(thing);
System.out.println(thing);
}
return stuff;
}});
scheduler.scheduleAtFixedRate(ft1, 0, 1, TimeUnit.SECONDS);
System.out.println(ft1.get());
System.out.println(ft1.isDone());
}
}
Tôi không chắc chắn tôi làm theo điều này. FutureTask thực hiện Runnable, và tôi mong đợi nó sẽ gọi phương thức call() và lưu trữ kết quả. Sau đó, tôi sẽ nhận được() để chặn cho đến khi công việc được thực hiện hoặc trả về kết quả được lưu trong bộ nhớ cache ngay lập tức. Vì vậy, không phải lịch trình chạy FutureTask, dẫn đến cuộc gọi() và kết quả được lưu trữ để thu thập sau này? –
Có, nhưng chỉ một lần. Bất kỳ lời gọi được lên lịch nào sau lần gọi đầu tiên sẽ gọi 'run' trên FutureTask, nhưng phương thức chạy" short-circuit "đó mà không gọi' call' trên Callable. Nhưng bộ lập lịch không nhận thức được điều này và tiếp tục chạy để gọi FutureTask, do đó chương trình không chấm dứt. – erickson
Làm cho cảm giác hoàn hảo. Tôi đã đi xuống trong javadocs cho các Executors và ilk của nó và tôi hoàn toàn bỏ lỡ dòng rõ ràng đó trong FutureTask. Như một câu hỏi tiếp theo, nếu những gì tôi muốn xảy ra là kết quả của nhiệm vụ của tôi là một BlockingQueue được cập nhật, nó là thích hợp hơn để chỉ cần chuyển hàng đợi đó vào mỗi runnable, hoặc để thực hiện một người nghe sẽ sống bên ngoài runnable mà sau đó thao tác hàng đợi dựa trên kết quả? Cảm ơn một lần nữa –