FutureTask是一種可以取消的異步的計算任務。它的計算是通過Callable實作的,它等價于可以攜帶結果的Runnable,并且有三個狀态:等待、運作和完成。完成包括所有計算以任意的方式結束,包括正常結束、取消和異常。
Future有個get方法而擷取結果隻有在計算完成時擷取,否則會一直阻塞直到任務轉入完成狀态,然後會傳回結果或者抛出異常。
FutureTask有下面幾個重要的方法:
1.get()
阻塞一直等待執行完成拿到結果
2.get(int timeout, TimeUnit timeUnit)
阻塞一直等待執行完成拿到結果,如果在逾時時間内,沒有拿到抛出異常
3.isCancelled()
是否被取消
4.isDone()
是否已經完成
5.cancel(boolean mayInterruptIfRunning)
試圖取消正在執行的任務
用ThreadPoolExecutor和FutureTask實作可取消任務線程池
http://jlusdy.iteye.com/blog/476667
private Map<String, FutureTask<String>> tasks = new HashMap<String, FutureTask<String>>();
// 構造一個線程
private ThreadPoolExecutor executor = new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>());
public void addTaskList(List<Callable<String>> tasksList) {
for (Callable<String> t : tasksList) {
FutureTask<String> futureTask = new FutureTask<String>(t);
executor.execute(futureTask);
String key = Long.toHexString(System.nanoTime());
tasks.put(key, futureTask);
}
}
public String addTask(Callable<String> task) {
FutureTask<String> futureTask = new FutureTask<String>(task);
executor.execute(futureTask);
String key = Long.toHexString(System.nanoTime());
tasks.put(key, futureTask);
return key;
}
public String addDBTask(Callable<String> task) {
FutureTask<String> futureTask = new FutureTask<String>(task) {
public boolean cancel(boolean mayInterruptIfRunning) {
System.out.println("Roll Back and Closs Session");
return super.cancel(mayInterruptIfRunning);
}
};
executor.execute(futureTask);
String key = Long.toHexString(System.nanoTime());
tasks.put(key, futureTask);
return key;
}
public boolean taskIsDone(String key) {
FutureTask<String> futureTask = tasks.get(key);
if (futureTask != null) {
return futureTask.isDone();
}
return false;
}
public boolean taskIsCancelled(String key) {
FutureTask<String> futureTask = tasks.get(key);
if (futureTask != null) {
return futureTask.isCancelled();
}
return false;
}
public String getTaskResult(String key) {
FutureTask<String> futureTask = tasks.get(key);
if (futureTask.isDone()) {
try {
String result = futureTask.get();
tasks.remove(key);
return result;
} catch (InterruptedException e) {
e.printStackTrace();
return null;
} catch (ExecutionException e) {
e.printStackTrace();
return null;
}
} else {
return null;
}
}
public String addTaskAndWaitResult(Callable<String> task) {
FutureTask<String> futureTask = new FutureTask<String>(task);
executor.execute(futureTask);
String key = Long.toHexString(System.nanoTime());
tasks.put(key, futureTask);
try {
return futureTask.get();
} catch (InterruptedException e) {
e.printStackTrace();
return null;
} catch (ExecutionException e) {
e.printStackTrace();
return null;
}
}
public void removeAllTask() {
for (String key : tasks.keySet()) {
executor.remove((Runnable) tasks.get(key));
tasks.remove(key);
}
}
public void removeQueryTask(String key) {
executor.remove((Runnable) tasks.get(key));
}
public void removeTask(String key) {
tasks.remove(key);
}
public void clearTaskList() {
tasks.clear();
}
public synchronized void stop(){
try {
executor.shutdownNow();
executor.awaitTermination(1L, TimeUnit.MILLISECONDS);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
executor = null;
tasks.clear();
tasks = null;
}
}
public void cancelTask(String key) {
FutureTask<String> futureTask = tasks.get(key);
if (futureTask != null) {
if (!futureTask.isDone()) {
futureTask.cancel(true);
}
}
}
public void purgeCancelTask() {
executor.purge();
executor.getQueue();
}
public static void main(String[] args) {
ImageSearchThreadPool exec = new ImageSearchThreadPool();
ArrayList<String> keyList = new ArrayList<String>();
ArrayList<String> removeKeyList = new ArrayList<String>();
ArrayList<String> cancelKeyList = new ArrayList<String>();
for (int i = 0; i < 10; i++) {
// 産生一個任務,并将其加入到線程池
String task = "task@ " + (i + 1);
System.out.println("put " + task);
keyList.add(exec.addDBTask(new DBTask(task)));
}
try {
Thread.sleep(1L);
} catch (InterruptedException e) {
e.printStackTrace();
}
for (int i = 0; i < 10; i++) {
if (exec.taskIsDone(keyList.get(i))) {
System.out.println(exec.getTaskResult(keyList.get(i)));
exec.removeTask(keyList.get(i));
removeKeyList.add(keyList.get(i));
} else {
exec.cancelTask(keyList.get(i));
System.out.println("Cancel task: " + (i + 1));
exec.removeTask(keyList.get(i));
cancelKeyList.add(keyList.get(i));
}
}
exec.purgeCancelTask();
exec.stop();
try {
Thread.sleep(6000L);
} catch (InterruptedException e) {
e.printStackTrace();
}
for (String key : cancelKeyList) {
if (exec.taskIsCancelled(key)) {
System.out.println("Cancel: " + key);
}
}
for (int i = 0; i < 10; i++) {
keyList.get(i);
}
}
線程池學習:http://www.cnblogs.com/jersey/archive/2011/03/30/2000231.html