打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
两个例子解释Callable 和 Future接口

Callable是类似于Runnable的接口,实现Callable接口的类和实现Runnable的类都是可被其它线程执行的任务。Callable和Runnable有几点不同:

Callable规定的方法是call(),而Runnable规定的方法是run().

Callable的任务执行后可返回值,而Runnable的任务是不能返回值的。

call()方法可抛出异常,而run()方法是不能抛出异常的。

运行Callable任务可拿到一个Future对象,通过Future对象可了解任务执行情况,可取消任务的执行,还可获取任务执行的结果。

以下是Callable的一个例子:

public class DoCallStuff implements Callable{ // *1

        private int aInt;

        public DoCallStuff(int aInt) {

                this.aInt = aInt;

        }

        public String call() throws Exception { //*2

                boolean resultOk = false;

                if(aInt == 0){

                        resultOk = true;

                }  else if(aInt == 1){

                        while(true){ //infinite loop

                                System.out.println("looping....");

                                Thread.sleep(3000);

                        }

                } else {

                        throw new Exception("Callable terminated with Exception!"); //*3

                }

                if(resultOk){

                        return "Task done.";

                } else {

                        return "Task failed";

                }

        }

}

*1: 名为DoCallStuff类实现了Callable,String将是call方法的返回值类型。例子中用了String,但可以是任何Java类。

*2: call方法的返回值类型为String,这是和类的定义相对应的。并且可以抛出异常。

*3: call方法可以抛出异常,如加重的斜体字所示。

以下是调用DoCallStuff的主程序。

import java.util.concurrent.ExecutionException;

import java.util.concurrent.ExecutorService;

import java.util.concurrent.Executors;

import java.util.concurrent.Future;

public class Executor {

        public static void main(String[] args){

                //*1

                DoCallStuff call1 = new DoCallStuff(0);

                DoCallStuff call2 = new DoCallStuff(1);

                DoCallStuff call3 = new DoCallStuff(2);

                //*2

                ExecutorService es = Executors.newFixedThreadPool(3);

                //*3

                Future future1 = es.submit(call1);

                Future future2 = es.submit(call2);

                Future future3 = es.submit(call3);

                try {

                        //*4

                        System.out.println(future1.get());

                         //*5

                        Thread.sleep(3000);

                        System.out.println("Thread 2 terminated? :" + future2.cancel(true));

                        //*6

                        System.out.println(future3.get());

                } catch (ExecutionException ex) {

                        ex.printStackTrace();

                } catch (InterruptedException ex) {

                        ex.printStackTrace();

                }

        }

}

*1: 定义了几个任务

*2: 初始了任务执行工具。任务的执行框架将会在后面解释。

*3: 执行任务,任务启动时返回了一个Future对象,如果想得到任务执行的结果或者是异常可对这个Future对象进行操作。Future所含的值必须跟Callable所含的值对映,比如说例子中Future对印Callable

*4: 任务1正常执行完毕,future1.get()会返回线程的值

*5: 任务2在进行一个死循环,调用future2.cancel(true)来中止此线程。传入的参数标明是否可打断线程,true表明可以打断。

*6: 任务3抛出异常,调用future3.get()时会引起异常的抛出。

 运行Executor会有以下运行结果:

looping....

Task done. //*1

looping....

looping....//*2

looping....

looping....

looping....

looping....

Thread 2 terminated? :true //*3

//*4

java.util.concurrent.ExecutionException: java.lang.Exception: Callable terminated with Exception!

        at java.util.concurrent.FutureTask$Sync.innerGet(FutureTask.java:205)

        at java.util.concurrent.FutureTask.get(FutureTask.java:80)

        at concurrent.Executor.main(Executor.java:43)

        …….

*1: 任务1正常结束

*2: 任务2是个死循环,这是它的打印结果

*3: 指示任务2被取消

*4: 在执行future3.get()时得到任务3抛出的异常

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
【第77题】JAVA高级技术-多线程11(创建线程的5种方式)
Java创建并执行线程的四种方法
Java多线程编程中Future模式的详解
Java并发中的执行器Executor/ExecutorService和ExecutorCompletionService | 三石·道
Future设计模式
Java:如何实现代码超时功能?
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服