Callable使用示例

之前工作中也有使用过Callable,但是却没有使用Thread对象去操作过,今晚 小组培训,涨知识了,现特意记录一下,以免忘记.

先看一下Thread的构造器

 可以看到,Thread类并没有提供参数是Callable的构造器, 但是Runnable是有的.

再看下面类关系图

   

所以,我们在使用Thread对象操作Callable实例时,完全可以使用FutureTask去包装一下下.

示例代码

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;

/**
 * 使用Callable示例
 */
public class FutureTest {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        FutureTask<Integer> task = new FutureTask<Integer>(new Callable<Integer>() {
            @Override
            public Integer call() throws Exception {
                int total = 0;
                for (int j = 0; j < 100; j++) {
                    System.out.println("total = "+ total);
                    total += j;
                }
                return total;
            }
        });

        Thread thread = new Thread(task);
        thread.start();

        Integer total = task.get();

        System.out.println("求和:" + total);
    }
}

在工作中,我们大多使用线程池对象操作Callable任务,并且获取任务返回值. 其实jdk提供的线程池ThreadPoolExecutor类操作Callable任务也是通过FutureTask类来包装的,

下面是源码

  public <T> Future<T> submit(Callable<T> task) {
        if (task == null) throw new NullPointerException();
        RunnableFuture<T> ftask = newTaskFor(task);
        execute(ftask);
        return ftask;
    }
  protected <T> RunnableFuture<T> newTaskFor(Callable<T> callable) {
        return new FutureTask<T>(callable);
    }

涨知识了吧....

一下取消任务的正确姿势

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;

/**
 * 使用Callable示例
 */
public class FutureTest {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        FutureTask<Integer> task = new FutureTask<Integer>(new Callable<Integer>() {
            @Override
            public Integer call() throws Exception {
                int total = 0;
                for (int j = 0; j < 100; j++) {
                    if (Thread.currentThread().isInterrupted()) {
                        System.out.println("取消任务...");
                        return null;
                    }
                    System.out.println("total = " + total);
                    total += j;
                }
                return total;
            }
        });

        Thread thread = new Thread(task);
        thread.start();
//        便于测试观察,主线程睡1ms
        Thread.currentThread().sleep(1);
//        取消任务
        task.cancel(true);
    }
}    





task.cancle(true): 该方法并不会真正的取消任务,它只会给任务线程打上一个终断的标识,相当于说,主线程说你可以停了....
Thread.currentThread().isInterrupted() : 任务线程检测自个身上是否有终断标识,如果发现有终断任务的标识, 好吧,我不干了,结束任务....
 
原文地址:https://www.cnblogs.com/z-qinfeng/p/12032455.html