JDK提供了ExecutorService接口表示线程池,能够经过submit提交一个任务。html
ExecutorService executor = Executors.newFixedThreadPool(4); executor.submit(task);
但这里的task有个问题,由于继承制Runnable,若是但愿返回一个结果,只能用result来表示,这样主线程获取结果,就很不方便。java
class Task implements Runnable{ public String result; //只能将结果保存到result,再去读取 public void run(){ this.result = longTimeCalculation(); } }
所以JDK又提供了一个Callable<T>接口。app
相比Runnable接口,Callable<T>接口多了一个返回值。这样咱们就能够用submit()方法把一个Callable的task提交给executor,异步执行。异步
<table border="1"><tr><td>不须要返回结果</td><td>须要返回结果</td></tr><tr><td>Runnable</td><td>Callable</td></tr></table> 当咱们使用Callable<T>接口时候,咱们须要实现一个泛型接口。例如咱们指望返回值是一个String,咱们就写implements Callable<String>,并覆写call()方法。 ```#java class Task implements Callable<String>{ public String call() throws Exception{ return longTimeCalculation(); } } ``` ## 3. Future <font color="red">若是得到异步执行的结果呢?</font> ```#java Callable<String> task = new Task(); ExecutorService executor = Executors.newFixedThreadPool(4); Future<String> future = exector.submit(task); String result = future.get(); //可能阻塞 ``` <font color="blue">当咱们提交一个Callable任务之后,会同时得到一个Future对象。 接着在主线程的某个时刻调用Future对象的get()方法就能够得到异步执行的结果: * 在调用get()方法的时候,若是异步任务已经完成,就直接得到结果; * 若是异步任务未完成,那么get()方法就会阻塞,直到任务完成之后,返回结果。 </font>ui
Future<V>接口:表示一个将来可能会返回的结果this
get():返回一个异步执行的结果 get(long timeout, TimeUnit unit):指定一个最长的等待时间 cancel(boolean mayInterruptIfRunning):中断一个异步任务的执行 isDone():判断当前的异步任务是否已经完成
import java.io.BufferedReader; import java.io.InputStreamReader; import java.net.URL; import java.net.URLConnection; import java.util.concurrent.Callable; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; class DownloadTask implements Callable<String> { String url; public DownloadTask(String url){ this.url = url; } public String call() throws Exception { System.out.println("start download " + url + "..."); URLConnection conn = new URL(this.url).openConnection(); conn.connect(); try (BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()))){ String s = null; StringBuilder sb = new StringBuilder(); while ((s = reader.readLine()) != null) { sb.append(s).append("\n"); } return sb.toString(); } } } public class Main{ public static void main(String[] args) throws Exception{ ExecutorService executor = Executors.newFixedThreadPool(3); DownloadTask task = new DownloadTask("https://www.sina.com.cn"); Future<String> future = executor.submit(task); String html = future.get(); System.out.println(html); executor.shutdown(); } }