zoukankan      html  css  js  c++  java
  • java线程池异步

    什么时候使用异步?

    处理多个任务,某些任务比较耗时,可以用异步。

    异步线程

    新建一个类,实现Callable接口,重写call()方法。
    异步任务的结果,通过call()方法返回。
    实现Callable接口,call()结果就返回String类型。Object等其他类型同理。
    如果不需要返回结果,可以实现Runnable接口,重写run()方法。
    如果需要传递参数,可以写在构造方法中。

    • 如下:
    package com.sf.inc.oewm.service.thread;
    
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    import java.util.concurrent.Callable;
    import java.util.concurrent.CountDownLatch;
    
    public class AsyncTask implements Callable<String> {
    
        private String param;
    
        //构造方法传递参数
        public AsyncTask(String param) {
            this.param = param;
        }
    
        public String call()  {
            String result = null;
            try {
                result = doSomething(param);
                //休眠线程,是为了比较异步的时间,实际不需要用到
                Thread.sleep(4000);
            } catch (Exception e) {
                System.out.println("AsyncTask error.");
            }
    
            return result;
        }
    
        public String doSomething(String param)  {
            System.out.println("异步的参数:" + param);
            System.out.println("执行异步方法.");
            return "异步结果";
        }
    
    }
    
    

    线程池

    使用线程池,将任务提交到线程池中处理。
    submit()方法,会返回一个Future类型的对象。
    而Future.get()方法,可以取得异步任务的结果,也可以使用FutureTask.
    使用Future.get()后,主线程会阻塞,直到获得异步的结果,记得设置超时时间。

    import java.util.concurrent.*;
    
    public class SubmitTest {
        //定义线程池
        public static final ThreadPoolExecutor EXECUTOR = new ThreadPoolExecutor
                (5, 10, 100, TimeUnit.SECONDS,
                        new ArrayBlockingQueue<Runnable>(60),
                        Executors.defaultThreadFactory(),
                        new ThreadPoolExecutor.AbortPolicy());
    
        public static void main(String[] args) throws  InterruptedException {
            submitTask();
        }
    
        public static void submitTask() throws InterruptedException {
            System.out.println("准备异步测试.");
            long t1 = System.currentTimeMillis();
    
            AsyncTask asyncTask = new AsyncTask("参数1");
            System.out.println("将任务提交到线程池.");
            Future<String> future = EXECUTOR.submit(asyncTask);
            //也可以使用FutureTask,都可以用get()获取结果
    //        FutureTask<String> futureTask = new FutureTask<>(asyncTask);
    //        EXECUTOR.submit(futureTask);
    
            System.out.println("还没进行future get().");
            //休眠线程,是为了比较异步的时间,实际不需要用到
            Thread.sleep(2000);
    
            String result= null;
            //使用future.get()阻塞,等待结果,并设置超时时间
            try {
                result = future.get(5,TimeUnit.MINUTES);
            } catch (Exception e) {
                System.out.println("future get overtime.");
            }
            System.out.println("future get()得到的结果:" + result);
            System.out.println("总共消耗时间 : " + (System.currentTimeMillis() - t1));
            //实际操作不一定要shutdown
            EXECUTOR.shutdown();
        }
    }
    
    

    执行结果如下:

    准备异步测试.
    任务提交到线程池.
    还没进行future get().
    异步的参数:参数1
    执行异步方法.
    future get()得到的结果:异步结果
    总共消耗时间 : 4008
    

    可以看到,我们在main()方法中休眠了2秒,在异步任务中休眠了4秒,最终全部消耗的时间只有4秒多。
    通过异步,提高了处理任务的效率。

    java8的线程池异步

    如果异步任务不需要传递参数,可以直接使用lambda表达式,隐藏Callable实现类。

        public void submitTaskNoParam() throws ExecutionException, InterruptedException {
            //实战建议使用ThreadPoolExecutor自定义线程池,避免OOM,此处是为了方便示例
            ExecutorService executor = Executors.newFixedThreadPool(5);
            Future<String> future = executor.submit(() -> {
                System.out.println("执行异步任务.");
                return "异步结果";
            });
            String result = future.get(5,TimeUnit.MINUTES);
            System.out.println(result);
        }
    
    

    参考资料:

    https://www.cnblogs.com/expiator/p/14751838.html
    https://www.cnblogs.com/cjsblog/p/9267163.html

  • 相关阅读:
    js过滤HTML标签以及&nbsp;
    Sharepoint的web.config配置
    javascript 动态添加div等这样的标签包含一些元素
    SPMetal 日志导出Caml语句
    sitepage applicationPage 区别
    exchange部署的好处
    SPSiteDataQuery不完全使用手册
    WP7 开发(十二) WebBrowser控件
    WP7 开发(十一) Web Task
    WP7 开发(十四) ApplicationBar
  • 原文地址:https://www.cnblogs.com/expiator/p/14750525.html
Copyright © 2011-2022 走看看