zoukankan      html  css  js  c++  java
  • 廖雪峰Java11多线程编程-3高级concurrent包-7Future

    1. Runnable接口的限制

    JDK提供了ExecutorService接口表示线程池,可以通过submit提交一个任务。

        ExecutorService executor = Executors.newFixedThreadPool(4);
        executor.submit(task);
    

    但这里的task有个问题,因为继承制Runnable,如果希望返回一个结果,只能用result来表示,这样主线程获取结果,就很不方便。

    class Task implements Runnable{
        public String result; //只能将结果保存到result,再去读取
        public void run(){
            this.result = longTimeCalculation();
        }
    }
    

    因此JDK又提供了一个Callable接口。

    2. Callable接口

    相比Runnable接口,Callable接口多了一个返回值。这样我们就可以用submit()方法把一个Callable的task提交给executor,异步执行。

    不需要返回结果需要返回结果
    RunnableCallable
    当我们使用Callable接口时候,我们需要实现一个泛型接口。例如我们期望返回值是一个String,我们就写implements Callable,并覆写call()方法。 ```#java class Task implements Callable{ public String call() throws Exception{ return longTimeCalculation(); } } ``` ## 3. Future 如果获得异步执行的结果呢? ```#java Callable task = new Task(); ExecutorService executor = Executors.newFixedThreadPool(4); Future future = exector.submit(task); String result = future.get(); //可能阻塞 ``` 当我们提交一个Callable任务以后,会同时获得一个Future对象。 接着在主线程的某个时刻调用Future对象的get()方法就可以获得异步执行的结果: * 在调用get()方法的时候,如果异步任务已经完成,就直接获得结果; * 如果异步任务未完成,那么get()方法就会阻塞,直到任务完成以后,返回结果。

    Future接口:表示一个未来可能会返回的结果

        get():返回一个异步执行的结果
        get(long timeout, TimeUnit unit):指定一个最长的等待时间
        cancel(boolean mayInterruptIfRunning):中断一个异步任务的执行
        isDone():判断当前的异步任务是否已经完成
    

    4. 示例

    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("
    ");
                }
                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();
        }
    }
    
    

    5.总结:

    • 需要返回结果,使用Callable;不需要返回结果,使用Runnable
    • 提交Callable任务,可以获得一个Future对象
    • 可以用Future在将来某个时刻获得结果
  • 相关阅读:
    线性规划与网络流24题解题报告
    [bzoj4569][SCOI2016]萌萌哒-并查集+倍增
    [bzoj1002]轮状病毒-矩阵树定理
    [bzoj1005][HNOI2008]明明的烦恼-Prufer编码+高精度
    [bzoj3995][SDOI2015]道路修建-线段树
    [bzoj3993][SDOI2015]星际战争-二分+最大流
    [bzoj3994][SDOI2015]约数个数和-数论
    [bzoj3990][SDOI2015]排序-搜索
    [bzoj4518][Sdoi2016]征途-斜率优化
    [bzoj4515][Sdoi2016]游戏-树链剖分+李超线段树
  • 原文地址:https://www.cnblogs.com/csj2018/p/11020126.html
Copyright © 2011-2022 走看看