大家好,欢迎来到IT知识分享网。
Callable接口
先看看Callable接口的源码:
Callable是一个函数式接口,此时就可以用lambda表达式更简洁地使用它。Callable是个泛型接口,只有一个方法call,该方法返回类型就是传递进来的V类型。call方法还支持抛出异常.
与Callable对应的是Runnable接口,实现了这两个接口的类都可以当做线程任务递交给线程池执行,Runnable接口的源码如下:
Runnable和Callable的区别:
- Runnable接口里执行线程任务是在run方法里写的,Callable接口里执行线程任务是在call方法里写;
- Callable的任务执行后可返回值,而Runnable的任务是不能返回值得;
- call方法可以抛出异常,run方法不可以;
- 加入线程池运行,Runnable使用ExecutorService的execute方法,Callable使用ExecutorService的submit方法;
- 运行Callable任务可以拿到一个Future对象,表示异步计算的结果.Future对象封装了检查计算是否完成、可取消任务的执行,检索计算的结果的方法;
Further接口
Further接口的源码如下:
- Future是一个接口,代表了一个异步计算的结果。接口中的方法用来检查计算是否完成、等待完成和得到计算的结果。
- get()方法 : 当计算完成后,只能通过get()方法得到结果,get方法会阻塞直到结果准备好了。
- cancel()方法 : 如果想取消,那么调用cancel()方法,但如果计算完了,就不能调用cancel方法了。
- isCanceled()方法 : 检查任务是否被取消成功了.
- isDone()方法 : 检查任务是否完成 。
FutureTask类
- Future是一个接口,FutureTask是Future接口的唯一实现类,一般用的时候向上转型,使用Future。
- FutureTask类实现的是RunnableFuture接口.
- 该接口继承了Runnable接口和Future接口,因此FutureTask类既可以当做线程任务递交给线程池执行,又能当Callable任务的计算结果。
- FutureTask可以用来包装Callable或者Runnbale对象。因为FutureTask实现了Runnable接口,所以FutureTask也可以被提交给Executor
Callable的两种实现方法
一.使用FutureTask实现
- 创建一个类,如MyCallableTask,实现Callable接口。
- 在MyCallableTask类中重写call()方法,定义线程需要执行的操作。
- Callable接口的call()方法可以有返回值,并且能够抛出异常。
import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.FutureTask; //定义实现Callable接口的的实现类重写call方法。 public class MyCallableTask implements Callable<Integer>{ @Override public Integer call() throws Exception { //TODO 线程执行方法 return -1; } } public class Test7 { public static void main(String[] args) throws ExecutionException, InterruptedException { //创建Callable对象 Callable<Integer> mycallabletask = new MyCallableTask(); //开始线程 FutureTask<Integer> futuretask = new FutureTask<Integer>(mycallabletask); new Thread(futuretask).start(); //通过futuretask可以得到MyCallableTask的call()的运行结果: futuretask.get(); } }
二.使用线程池实现
举两个例子:
public class CallableTest { public static void main(String[] args) throws ExecutionException, InterruptedException,TimeoutException{ //创建一个线程池 ExecutorService executor = Executors.newCachedThreadPool(); //使用submit()方法来执行线程,此处使用的是lambda表达式 Future<String> future = executor.submit(()-> { TimeUnit.SECONDS.sleep(5); return "CallableTest"; }); System.out.println(future.get()); executor.shutdown(); } }
public class CallableAndFuture { public static void main(String[] args) { Random random = new Random(); //创建一个线程池 ExecutorService threadPool = Executors.newSingleThreadExecutor(); Future<Integer> future = threadPool.submit(new Callable<Integer>() { public Integer call() throws Exception { return random.nextInt(10000); } }); try { Thread.sleep(3000); System.out.println(future.get()); } catch (Exception e) { e.printStackTrace(); } } }
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/156425.html