متد get یک Future باید زمانی فراخوانی شود که جواب یک Future آماده شده است (با متد isDone می توان به این مسئله پی برد) و در غیر اینصورت همزمانی به مشکل بر می خورد. با یک مثال کاملا همه چیز مشخص می شود.
private static final ExecutorService pool = Executors.newFixedThreadPool(10);
public static Future<String> startComputation() throws IOException {
return pool.submit(new Callable<String>() {
@Override
public String call() throws Exception {
Thread.currentThread().sleep(3000);
return "finish computation";
}
});
}
public static void main(String[] args) throws IOException, InterruptedException, ExecutionException {
final Future<String> contentsFuture = startComputation();
while (!contentsFuture.isDone()) {
System.out.println("computation in progress...");
System.out.println("do another work");
Thread.currentThread().sleep(1000);
}
System.out.println(contentsFuture.get());
System.exit(0);
}
خروجی کد بالا بصورت زیر است:
computation in progress...
do another work
computation in progress...
do another work
computation in progress...
do another work
finish computation
همانطور که می بینید برای انجام یک کار محاسباتی فرضی که 3 ثانیه طول می کشد تا نتیجه Future آن آمده شود با درست قرار دادن فراخوانی متد get توانسته ایم 3 کار 1 ثانیه ای دیگر را نیز در این فاصله انجام دهیم.
حالا فراخوانی متد get را بدرون while می بریم و قبل از آماده شدن نتیجه به اشتباه آن را فراخوانی می کنیم.
private static final ExecutorService pool = Executors.newFixedThreadPool(10);
public static Future<String> startComputation() throws IOException {
return pool.submit(new Callable<String>() {
@Override
public String call() throws Exception {
Thread.currentThread().sleep(3000);
return "finish computation";
}
});
}
public static void main(String[] args) throws IOException, InterruptedException, ExecutionException {
final Future<String> contentsFuture = startComputation();
while (!contentsFuture.isDone()) {
System.out.println("computation in progress...");
System.out.println("do another work");
Thread.currentThread().sleep(1000);
System.out.println(contentsFuture.get());
}
System.exit(0);
}
خروجی تکه کد بالا بصورت زیر است:
computation in progress...
do another work
finish computation
همانطور که می بینید بدلیل فراخوانی اشتباه متد get، از کل ظرفیت همزمانی سیستم استفاده نشده است ولی سیستم به مشکل بر نخورده است.