Concurrency>cat RenderWithTimeBudget.java
import java.util.concurrent.*;
import static java.util.concurrent.TimeUnit.NANOSECONDS;
/**
* RenderWithTimeBudget
*
* Fetching an advertisement with a time budget
*/
public class RenderWithTimeBudget {
private static final Ad DEFAULT_AD = new Ad("DefaultAd");
private static final long TIME_BUDGET = 1000;
private static final ExecutorService exec = Executors.newCachedThreadPool();
public static void main(String ... args) {
RenderWithTimeBudget rwtb = new RenderWithTimeBudget();
Page page;
try {
page = rwtb.renderPageWithAd(0);
System.out.println(page.getAd().AdStr + "\n" +page.toString());
page = rwtb.renderPageWithAd(3000);
System.out.println(page.getAd().AdStr + "\n" +page.toString());
exec.shutdown();
exec.awaitTermination(10, TimeUnit.SECONDS);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
Page renderPageWithAd(long delay) throws InterruptedException {
long endNanos = System.nanoTime() + TIME_BUDGET;
Future<Ad> f = exec.submit(new FetchAdTask());
// Render the page while waiting for the ad
Page page = renderPageBody();
Thread.sleep(delay);
Ad ad;
try {
// Only wait for the remaining time budget
long timeLeft = endNanos - System.nanoTime();
ad = f.get(timeLeft, NANOSECONDS);
} catch (ExecutionException e) {
ad = DEFAULT_AD;
} catch (TimeoutException e) {
ad = DEFAULT_AD;
f.cancel(true);
}
page.setAd(ad);
return page;
}
Page renderPageBody() { return new Page(); }
static class Ad {
String AdStr = "";
Ad(String ad) {
AdStr = ad;
}
}
static class Page {
Ad ad;
public void setAd(Ad ad) {this.ad = ad; }
public Ad getAd() {return ad;}
}
static class FetchAdTask implements Callable<Ad> {
public Ad call() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
System.out.println("interrupted when cancel is called");
Thread.currentThread().interrupt();
}
return new Ad("FetchedAd");
}
}
}
Concurrency>javac RenderWithTimeBudget.java
Concurrency>java RenderWithTimeBudget
interrupted when cancel is called
DefaultAd
RenderWithTimeBudget$Page@42a57993
FetchedAd
RenderWithTimeBudget$Page@75b84c92
Concurrency>