• java如何异步方式处理业务逻辑


    1.基础类-java.util.concurrent.ExcutorService

    这个类的几个重要函数

    shutdown 关闭任务池,无法传入新任务

    shutdownnow 关闭所有任务,包括未执行完成的任务

    submit 向任务池提交任务

    2.基础接口-java.util.concurrent.Future

    Future就是对于具体的Runnable或者Callable任务的执行结果进行取消、查询是否完成、获取结果。必要时可以通过get方法获取执行结果,该方法会阻塞直到任务返回结果。

    FutureTask 是实现了Future接口和Runnable接口,RunnableFuture接口

    public class Test {
        public static void main(String[] args) {
            ExecutorService executor = Executors.newCachedThreadPool();
            Task task = new Task();
            Future<Integer> result = executor.submit(task);
            executor.shutdown();
             
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e1) {
                e1.printStackTrace();
            }
             
            System.out.println("主线程在执行任务");
             
            try {
                System.out.println("task运行结果"+result.get());
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (ExecutionException e) {
                e.printStackTrace();
            }
             
            System.out.println("所有任务执行完毕");
        }
    }
    class Task implements Callable<Integer>{
        @Override
        public Integer call() throws Exception {
            System.out.println("子线程在进行计算");
            Thread.sleep(3000);
            int sum = 0;
            for(int i=0;i<100;i++)
                sum += i;
            return sum;
        }
    }
    --------------------------------------------------------------------------
    public class Test {
        public static void main(String[] args) {
            //第一种方式
            ExecutorService executor = Executors.newCachedThreadPool();
            Task task = new Task();
            FutureTask<Integer> futureTask = new FutureTask<Integer>(task);
            executor.submit(futureTask);
            executor.shutdown();
             
            //第二种方式,注意这种方式和第一种方式效果是类似的,只不过一个使用的是ExecutorService,一个使用的是Thread
            /*Task task = new Task();
            FutureTask<Integer> futureTask = new FutureTask<Integer>(task);
            Thread thread = new Thread(futureTask);
            thread.start();*/
             
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e1) {
                e1.printStackTrace();
            }
             
            System.out.println("主线程在执行任务");
             
            try {
                System.out.println("task运行结果"+futureTask.get());
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (ExecutionException e) {
                e.printStackTrace();
            }
             
            System.out.println("所有任务执行完毕");
        }
    }
    class Task implements Callable<Integer>{
        @Override
        public Integer call() throws Exception {
            System.out.println("子线程在进行计算");
            Thread.sleep(3000);
            int sum = 0;
            for(int i=0;i<100;i++)
                sum += i;
            return sum;
        }
    }
    ----------------------------------------------------------------------------------
    3.StaticMethod.getResult方法的优化版本,异步方式
    /**
         * getResult 的优化版本 异步,非阻塞方式
         * @author jwjw233233@163.com
         * @param url 接口地址
         * @param param 接口参数
         */
        public static void getResult_Asynchronous(final String url, final String param) {
            ExecutorService es = Executors.newCachedThreadPool();
            es.submit(new Callable<String>() {
                @Override
                public String call() throws Exception {
                    PrintWriter out = null;
                    BufferedReader in = null;
                    String result = "";
                    try {
                        URL realUrl = new URL(url);
                        // 打开和URL之间的连接
                        URLConnection conn = realUrl.openConnection();
                        // 设置通用的请求属性
                        conn.setRequestProperty("accept", "*/*");
                        conn.setRequestProperty("connection", "Keep-Alive");
                        conn.setRequestProperty("user-agent",
                                "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)");
                        // 发送POST请求必须设置如下两行
                        conn.setDoOutput(true);
                        conn.setDoInput(true);

                        // 获取URLConnection对象对应的输出流
                        out = new PrintWriter(new OutputStreamWriter(conn.getOutputStream(), "utf-8"));
                        // 发送请求参数
                        out.print(param);
                        // flush输出流的缓冲
                        out.flush();
                        // 定义BufferedReader输入流来读取URL的响应
                        in = new BufferedReader(new InputStreamReader(conn.getInputStream(), "UTF-8"));
                        String line;
                        while ((line = in.readLine()) != null) {
                            result += line;
                        }
                    } catch (Exception e) {
                        System.out.println("发送POST请求出现异常!" + e);
                        System.out.println("url=" + url + "?" + param);
                    }
                    // 使用finally块来关闭输出流、输入流
                    finally {
                        try {
                            if (out != null) {
                                out.close();
                            }
                            if (in != null) {
                                in.close();
                            }
                        } catch (IOException ex) {
                        }
                    }
                    return result;
                }

            });
            es.shutdown();
        }

    ----------------------------------------------------------------------------

    测试函数

    public static void main(String[] args) {
            System.out.println(new Date());
            StaticMethod.getResult_Asynchronous("http://cs.jiwu.com/build!home.action?bid=3343", "");
            System.out.println(new Date());
            
            System.out.println(new Date());
            StaticMethod.getResult("http://cs.jiwu.com/build!home.action?bid=3343", "");
            System.out.println(new Date());
        }

    输出结果:

    Fri Apr 15 14:41:22 CST 2016
    Fri Apr 15 14:41:22 CST 2016
    Fri Apr 15 14:41:22 CST 2016
    Fri Apr 15 14:41:32 CST 2016

    ---------------------------------------------------------------------------------------------------------

     结论:采用异步方式更新一个楼盘页 几乎不需要等待,而采用同步方式却花费了10s的时间,性能有巨大差距!

  • 相关阅读:
    sql小练习
    登录测试点
    游戏签到
    移动端和pc端微信加入群聊
    小说
    微信语言输入
    linux tar压缩解压缩命令详解
    linux使用nginx配置web服务器
    FFmpeg 视频处理入门教程
    Git学习
  • 原文地址:https://www.cnblogs.com/jiwuyf/p/5395466.html
Copyright © 2020-2023  润新知