码迷,mamicode.com
首页 > 编程语言 > 详细

Java并发编程之Callable,Future,FutureTask

时间:2015-08-04 19:20:49      阅读:246      评论:0      收藏:0      [点我收藏+]

标签:callable   future   futuretask   java并发编程   

创建线程:
1. 继承Thread
2. 实现Runnable
仔细观察会发现void run() ,这个方法没有返回值,也就无法获得线程执行结果。

Callable

返回结果并且可能抛出异常的任务。实现者定义了一个不带任何参数的叫做 call 的方法。

Callable 接口类似于 Runnable,两者都是为那些其实例可能被另一个线程执行的类设计的。但是 Runnable 不会返回结果,并且无法抛出经过检查的异常。

V call()
计算结果,如果无法计算结果,则抛出一个异常。
跟Runnable功能类似,用于创建线程,但是call方法有返回值
V - call 方法的结果类型

Future

接口 Future<V>
V - 此 Future 的 get 方法所返回的结果类型
Future 表示异步计算的结果。它提供了检查计算是否完成的方法【isDone()】,以等待计算的完成,并获取计算的结果【get()】。计算完成后只能使用 get 方法来获取结果,如有必要,计算完成前可以阻塞此方法。取消则由 cancel 方法来执行。还提供了其他方法,以确定任务是正常完成还是被取消了【isCancelled() 】。一旦计算完成,就不能再取消计算。如果为了可取消性而使用 Future 但又不提供可用的结果,则可以声明 Future<?> 形式类型、并返回 null 作为底层任务的结果。

FutureTask

实现了Future接口
类 FutureTask<V>
类型参数:
V - 此 FutureTask 的 get 方法所返回的结果类型。

可取消的异步计算。利用开始和取消计算的方法、查询计算是否完成的方法和获取计算结果的方法,此类提供了对 Future 的基本实现。仅在计算完成时才能获取结果;如果计算尚未完成,则阻塞 get 方法。一旦计算完成,就不能再重新开始或取消计算。

方法 意义
FutureTask(Callable<V> callable) 创建一个 FutureTask,一旦运行就执行给定的 Callable。
FutureTask(Runnable runnable, V result) 创建一个 FutureTask,一旦运行就执行给定的 Runnable,并安排成功完成时 get 返回给定的结果 。
boolean cancel(boolean mayInterruptIfRunning) 试图取消对此任务的执行。
protected void done() 当此任务转换到状态 isDone(不管是正常地还是通过取消)时,调用受保护的方法。
V get() 如有必要,等待计算完成,然后获取其结果。
V get(long timeout, TimeUnit unit) 如有必要,最多等待为使计算完成所给定的时间之后,获取其结果(如果结果可用)。
boolean isCancelled() 如果在任务正常完成前将其取消,则返回 true。
boolean isDone() 如果任务已完成,则返回 true。
void run() 除非已将此 Future 取消,否则将其设置为其计算的结果。
protected boolean runAndReset() 执行计算而不设置其结果,然后将此 Future 重置为初始状态,如果计算遇到异常或已取消,则该操作失败。
protected void set(V v) 除非已经设置了此 Future 或已将其取消,否则将其结果设置为给定的值。

实例

我们可以这样理解,FutureTask就是一个后台线程,它不同于一般的实现Runnable的线程,FutureTask封装了信息,并且会保存结果。当我们对结果感兴趣的任意时刻,可以直接调用get方法。

SwingWorker(实现了Future接口)其实就是一个很好的例子
一方面界面要相应用户的鼠标点击事件,一方面需要去计算耗时的任务(比如计算素数)。如果将计算任务安排在主线程里,就会造成界面的卡死,即相应不了用户的点击事件。因此可以借用SwingWork

public class TestFutureTask 
{
    public static void main(String[] args) throws Exception
    {
        System.out.println("Hello World!");
        FutureTask futureTask = new FutureTask(new CalculateTask());
        Thread task = new Thread(futureTask);
        task.start();
        //监控计算任务是否结束
        while(!futureTask.isDone()){
            System.out.println("响应用户其他的需求...");
            //Thread.sleep(300);
        }

        //获取结果,如果结果没有准备好,则会阻塞在这里
        System.out.println(futureTask.get());
    }
}
class CalculateTask implements Callable<List<Integer>>
{
    /*
    *   计算12321可以由那两个素数相加得到
    */
    @Override
    public List<Integer> call() throws Exception{
        List<Integer> list = new ArrayList<Integer>();
        long start = System.currentTimeMillis();
        int count = 0;
        for(int i = 2; i < 12321 ; i ++){
            if(isPrime(i)){
                count++;
                System.out.print(i + "\t");
                if(count % 20 == 0){
                    System.out.println();
                }
            }

        }
        System.out.println("\n共有素数:" + count);
        for(int i = 2; i <= 12321/2 ; i ++){
            //System.out.println(i+","+(12321-i));
            if(isPrime(i) && isPrime(12321 - i)){
                list.add(i);
                list.add(12321 - i);
            }
            //Thread.sleep(500);
        }
        System.out.println("计算结果耗时:" + (System.currentTimeMillis() - start)+"ms");
        return list;
    }
    public static boolean isPrime(int prime){
        int num = (int)Math.sqrt(prime);
        for(int i = 2; i <= Math.sqrt(prime) ; i ++){
            if(prime % i == 0){
                return false;
            }
        }
        return true;
    }
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

Java并发编程之Callable,Future,FutureTask

标签:callable   future   futuretask   java并发编程   

原文地址:http://blog.csdn.net/havedream_one/article/details/47280065

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!