在Java中,建设线程一般有两种方法,一种是担任Thread类,一种是实现Runnable接口。然而,这两种方法的缺点是在线程任务执行竣事后,无法获取执行功效。我们一般只能回收共享变量或共享存储以及线程通信的方法实现得到任务功效的目标;
不外,在Java中,也提供了利用Callable和Future来实现获取任务功效的操纵。Callable用来执行任务,发生功效,而Future用来得到功效;
@FunctionalInterface public interface Callable<V> { /** * Computes a result, or throws an exception if unable to do so. * * @return computed result * @throws Exception if unable to compute a result */ V call() throws Exception; }
线程实现方法:
1.担任Thread类
2.实现Runnable接口
3.线程池
4.Callable
无论利用担任Thread类照旧实现Runnable接口,照旧利用线程池都没有步伐办理2个问题
1.线程执行没有返回值功效
2.线程执行没有步伐抛出异常,只能本身通过try-catch办理
Callable和Runnable雷同,在JUC包下,主要区别在于Callable中的call要领可以带返回值而且可以抛出异常
假如需要执行Callable,需要Future实现类的支持,可以或许接管返回值功效,FutureTask是Future实现类
Future莫斯的焦点在于:去除了函数的期待时间,并使得本来需要期待的时间段可以用于处理惩罚其他业务逻辑;
Future模式:对付多线程,假如线程A要期待线程B的功效,那么线程A没有须要期待线程B,知道线程B有功效,可以先拿到一个将来的Future,等线程B有功效时再取真实的功效;
public class MyCallable implements Callable { @Override public Object call() throws Exception { System.out.println("callable接口中重写的call要领,可以有返回值而且抛出异常!!!"); return "callable"; } //方案一 public static void main(String[] args) throws ExecutionException, InterruptedException { MyCallable myCallable = new MyCallable(); //操作FutureTask执行callable而且接管布局 FutureTask<String> stringFutureTask = new FutureTask<String>(myCallable); //操作线程执行task任务 new Thread(stringFutureTask).start(); //接管功效,get要了解产生阻塞环境 System.out.println(stringFutureTask.get()); System.out.println("mycallable执行完毕!"); } }
public class MyCallable implements Callable { @Override public Object call() throws Exception { System.out.println("callable接口中重写的call要领,可以有返回值而且抛出异常!!!"); return "callable"; } //方案二:submit(Callable task) public static void main(String[] args) throws ExecutionException, InterruptedException { MyCallable myCallable = new MyCallable(); //建设一个线程 ExecutorService executorService = Executors.newFixedThreadPool(3); //建设线程执行任务,接管任务功效 Future submit = executorService.submit(myCallable); //接管返回值,get要了解阻塞当前线程 System.out.println(submit.get()); System.out.println("操作线程池执行mycallable,完毕!!!"); //遏制 executorService.shutdown(); } }
常用要领:
V get():获取异步执行的功效,假如没有功效可用,此要了解阻塞知道异步计较完成;
V get(Long timeout,TimeUnit unit):获取异步执行功效,假如没哟功效可用,此要了解阻塞,可是会有时间限制,假如阻塞时间高出设定的timeout时间,该要领将抛出异常;
boolean isDone():假如任务执行竣事,无论是正常竣事或是半途打消照旧产生异常,都返回true;
boolean isCanceller():假如任务完成前被打消,则返回true;
boolean cancel(boolean mayInterrupRunning):假如任务还没有开始,执行cancel要领将返回false;假如任务已经启动,执行cancel要领将以间断执行此任务线程的方法来试图遏制任务,假如遏制乐成,返回true;
当任务已经启动,执行cancel(false)要领将不会对正在执行的任务线程发生影响(让线程正常执行到完成),此时返回false;
当任务已经启动,执行cancel要领将返回false,MayInterruptRunning参数暗示是否间断执行中的线程;
实际上Future提供了三种成果:
1.可以或许间断执行中的任务;
2.判定任务是否执行完成;
3.获取任务执行完成后的功效;
get()要领的阻塞性