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 [email protected]
     * @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的时间,性能有巨大差距!

时间: 2024-11-07 14:31:35

java如何异步方式处理业务逻辑的相关文章

高效 告别996,开启java高效编程之门 3-2传统方式处理业务逻辑

1 重点 1.1 对sort方法使用的理解 2 代码演练 需求: 根据第一章需求,女盆友提出需求* 1 打印所有商品* 2 图书类的商品一定给买* 3 最贵的买两件* 4 打印最贵的两件商品的名称和总价 测试类: package com.imooc.zhangxiaoxi.stream; import com.alibaba.fastjson.JSON; import com.imooc.zhangxiaoxi.lambda.cart.CartService; import com.imooc.

业务逻辑实现方式选择

当业务逻辑相对复杂的时候,我的大脑中总会浮现出这样或者那样的解决方案,这些解决方案中有曾经使用过的和未使用过的.当面对这样的选择的时候,我的大脑是比较混乱的,总是想要去在开始还没有去做就抽象出一层,或者通通的放到一条sql中来完成,总感觉这样的方式是快捷的. 而实际中,我们在做这个页面的时候,前面已经有类似的页面,这个要做的页面也只是在上一个页面的基础上进行了些许的改动,那我为什么不把已经做好的页面直接拿过来,改动一些需要变化的部分,而不是自己去创造一套新的解决方案,或者实现方案,这样的每一步都

Java业务逻辑结合MySQL实现登录注册(XMPP协议的运用)

XMPP协议: 通信协议是一种约定的规则,XMPP也无外乎是一种接口规则.简单的说XMPP协议是一种标记格式的文本串. 举例: <msg><send>hxjava</send><content>helloworld</content></msg> 学习了XMPP协议之后,就实现C/S的登录注册操作,这一次的登录操作就不像以前那样用一些Map容器存储数据了. 存储数据要用数据库,这样不仅便于数据管理维护,而且数据不容易丢失,建立Map容

java中异常处理机制 throw抛出自定义业务逻辑异常 throws继续抛出 catch捕获后会自动继续抛向调用方法

package com.swift; public class Exception_TestC { public static void main(String[] args) { /* * 第5题: 有一个类为ClassA,有一个类为ClassB,在ClassB中有一个方法b,此方法抛出异常,在ClassA类中有一个 * 方法a,请在这个方法中调用b,然后抛出异常.在客户端有一个类为TestC,有一个方法为c ,请在这个方法中捕 捉异常的信息.Java异常的处理机制 * * 如果try或cat

java 业务逻辑理解

细说业务逻辑 2016年10月14日 07:16:28 阅读数:2295 细说业务逻辑   前言 记得几个月前,在一次北京博客园俱乐部的活动上,最后一个环节是话题自由讨论.就是提几个话题,然后大家各自加入感兴趣的话题小组,进行自由讨论.当时金色海洋同学提出了一个话题--"什么是业务逻辑".当时我和大家讨论ASP.NET MVC的相关话题去了,就没能加入"业务逻辑"组的讨论,比较遗憾. 其实,一段时间内,我脑子里对"业务逻辑"的概念也是非常模糊的.

微信开发处理超时5s(java),异步发送客服消息

在微信开发中我们会经常遇到在处理业务逻辑超过5s的情况,在超时时,微信会重新请求,总共请求三次,这样就会导致一系列的问题,怎样避免这些问题呢? 通过研究发现在微信官方文档清楚写着,如下: 假如服务器无法保证在五秒内处理并回复,必须做出下述回复,这样微信服务器才不会对此作任何处理,并且不会发起重试(这种情况下,可以使用客服消息接口进行异步回复),否则,将出现严重的错误提示.详见下面说明: 1.直接回复空串(指字节长度为0的空字符串,而不是XML结构体中content字段的内容为空) 2.直接回复s

MyBatis知多少(6)表现层与业务逻辑层

表现层 表现层负责向最终用户展示应用程序的控制方式以及数据.它还要负责所有信息的布局和格式.今天,商业应用程序最流行的表现方式应该算是Web前端了,它使用HTML和JavaScript并通 过Web浏览器来满足用户的界面外观需求. Web应用程序的优势包括跨平台兼容性.易部署和可扩展.amazon.com就是Web应用程序的—个极好的例子,它允许你在线购书.这就是Web应用程序的一个绝佳应用,因为不可能要求用 户为了买一本书而去下载一个应用程序. 当需要高级的用户控件或者复杂的数据操纵时,Web

java后台异步任务执行器TaskManager

java后台异步任务执行器TaskManager 此方式基于MVC方式: 一,使用任务: 1 @Resource 2 private TaskManager taskManager; 3 4 public string commit(TradeStatus status) { 5 if (status== TradeStatus.UNDERWAY) { 6 7 // 执行任务 8 taskManager.addTask(new Runnable() { 9 10 @Override 11 pub

表格存储新手指南:Java SDK异步接口的使用

原文地址 本篇文章主要会介绍下表格存储的Java SDK提供的异步接口,如何使用以及应用场景. 为什么需要异步? 异步提供了一个non-blocking, event-driven的编程模型,能够将系统不同层级的模块进行层次化的解耦,能够利用多核并行执行任务,提高性能. 现如今,一个大型的系统,系统级调优的最关键一步,就是异步化.异步化最常改造的是远程RPC或者数据库访问部分,表格存储作为一个底层数据库产品,需要提供异步接口来适应这个潮流. 在表格存储内部,我们也有一些使用异步来优化系统的例子,