转自:http://lf6627926.iteye.com/blog/1538313
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, newLinkedBlockingQueue<Runnable>());
/**
* @param tasksList
*/
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);
}
}
/**
* @param task
* @return
*/
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;
}
/**
* @param task
* @return
*/
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;
}
/**
* @param key
* @return
*/
public boolean taskIsDone(String key) {
FutureTask<String> futureTask = tasks.get(key);
if (futureTask != null) {
return futureTask.isDone();
}
return false;
}
/**
* @param key
* @return
*/
public boolean taskIsCancelled(String key) {
FutureTask<String> futureTask = tasks.get(key);
if (futureTask != null) {
return futureTask.isCancelled();
}
return false;
}
/**
* @param key
* @return
*/
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;
}
}
/**
* @param task
* @return
*/
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);
}
}
/**
* @param key
*/
public void removeQueryTask(String key) {
executor.remove((Runnable) tasks.get(key));
}
/**
* @param 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;
}
}
/**
* @param key
*/
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();
}
/**
* @param args
*/
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);
}
}