「java异步回调解决方案」java异步处理方法

博主:adminadmin 2023-03-17 04:50:06 612

本篇文章给大家谈谈java异步回调解决方案,以及java异步处理方法对应的知识点,希望对各位有所帮助,不要忘了收藏本站喔。

本文目录一览:

如何用Java回调和线程实现异步调用

软件模块之间的调用关系可以分为两大类:即同步调用和异步调用。在同步调用中,一段代码(主调方)调用另一段代码(被调方),主调方必须等待这段代码执行完成返回结果后,才能继续往下执行,所以,同步调用是一种阻塞式调用,主调方代码一直阻塞等待直到被调方返回为止。同步调用相对比较直观,也是大部分编程语言直接支持的一种调用方式。但是,同步调用在处理比较耗时的情况下会严重影响程序性能,影响人机交互的瞬时反应。例如,某个程序需要访问数据库获取大量数据,然后根据这些数据进行一系列处理,将处理结果显示在程序主窗口。由于数据库访问和大量数据的处理都是耗时的工作,在这个工作完成之前,处理结果迟迟不能显示,用户点击鼠标也不会立即得到响应,让用户感到整个程序显得很沉重。面对这样一些需要比较长时间才能完成的应用场景,我们需要采用一种非阻塞式调用方式,即异步调用方式。在异步调用中,主调方调用被调方后,不等待对方返回结果就继续执行后续代码,被调方执行完毕后,通过某种手段通知调用方:结果已经出来,请酌情处理。我们可以对上面的例子改用异步调用将问题轻松化解:把整个耗时的工作放进一个单独的线程,由主调方启动此线程后继续执行后续代码,线程在背后悄悄地处理费时的工作,当工作完成,采用回调的方式通知主调方工作完成,主调方将结果显示在主窗口。经过这样的处理,主界面继续进行自己的工作而不必死等,就不会造成界面响应迟钝。

在实现异步调用机制时,除了线程之外,还要用到回调。回调是一种双向调用,也就是,被调方在被调用时也会调用主调方的代码。在异步调用中,被调方需要在工作完成时通知主调方,即调用主调方的接口,这一机制通过回调实现。回调和异步调用的关系非常紧密,回调是异步调用的基础[1]。

本文理论联系实际,首先阐述如何使用Java实现回调机制,然后进一步阐述使用Java回调和线程实现异步调用,最后,阐述在异步调用中如何处理超时问题。

1 Java回调机制的实现方法

实现Java回调,需要做如下三件事情:

(1)定义一个回调接口CallbackInterface

接口中声明回调方法handle,如图1所示,回调方法就是一个普通的方法,接收一个消息字符串或者一个封装了数据的事件。

(2)定义一个类实现回调接口

这个类其实就是消息接收者和处理者,也就是调用方,回调方法是消息发生时实际处理消息的方法,此处简化为一条打印语句。

(3)定义消息通知者

消息通知者也就是被调用方必须具备两种能力,第一,它必须知道谁是消息接收者,第二,当消息发生时,它能够回调这些接收者的回调方法。为了获得这两种能力,消息通知者首先必须提供一个注册方法register, 通过注册的方式来注册多个对此消息或事件感兴趣的对象。然后提供一个消息通知方法notifyMessage,在这个方法中调用所有消息接收者的回调方法。具体代码如图3所示。

比如用一个可变数组List用于保存消息接收者,注册的过程实际上是将消息接收者添加到这个数组,以备在需要通知消息的时候调用这些消息接收者的回调方法。

使用Java回调和线程实现异步调用

线程是一个独立的执行流,其本质是程序中一段并发执行的代码。在异步调用机制中引入线程,在线程中完成耗时的工作,其目的是让调用方的主线程继续执行后续代码而不需要等待被调方的结果返回。由于不需要等待,这样我们就等于同时做了两件事情,而这两件事情分别是在不同的执行流中执行,主调者在当前的主线程中执行,被调者在另外一个线程中执行,因此提高了程序的效率,避免了界面的响应迟钝。当被调者执行完成后,仍然采用回调通知主调者。

例如 LongTimeWorker是一个用于完成耗时工作的线程,同时又是消息通知者。其耗时工作在run方法中完成,另外提供一个注册方法register, 和一个消息通知方法notifyMessage,在run方法的最后,即耗时工作完成以后,调用notifyMessage将消息广播出去。

3 异步调用中超时问题的处理

异步调用通常都要加入超时机制,因为我们总是希望在一个指定的时间范围内返回一个结果,即使没有得到结果也该有个超时通知。这时我们需要使用“限时线程回调方式”,它在原有线程回调的基础上加上一个计时器Timer以计算消耗的时间,如果时间期限到了任务还没有执行完成即中断线程,并将超时消息广播出去。LongTimeWorker类需要修改部分的代码如图8和图9所示。

首先LongTimeWorker线程类增加了一个构造方法,其参数是超时时间timeout,构造方法的主要任务是创建一个定时器,每秒钟计时一次,若超时时间到则终止本线程,并广播超时消息。LongTimeWorker线程类的第二个改变发生在其run方法中,线程一启动立即开始计时,完成工作后停止计时,并广播消息。

4 结束语

异步调用是一种非阻塞式调用方式,用于在处理比较耗时的任务时保证程序性能不受到影响。实现异步调用的关键在于要解决三个技术难题,它们分别是程序阻塞问题、异步消息的传递问题和超时问题。本文介绍的方法采用并发线程、回调机制和计时器使上述问题得到了圆满解决。

JAVA如何实现异步回调

FutureTaskString futureTask=new FutureTask(new CallableString() {

@Override

public String call() throws Exception {

// TODO Auto-generated method stub

return "回调完成";

}

});

try {

String str=futureTask.get();

if(str.equals("回调完成"))

System.out.println("异步任务完成!");

} catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

} catch (ExecutionException e) {

// TODO Auto-generated catch block

e.printStackTrace(); }

java接口怎么异步响应前端

1、异步概念

异步处理不用阻塞当前线程来等待处理完成,而是允许后续操作,直至其它线程将处理完成,并回调通知此线程。

必须强调一个基础逻辑,异步是一种设计理念,异步操作不等于多线程,MQ中间件,或者消息广播,这些是可以实现异步处理的方式。

同步处理和异步处理相对,需要实时处理并响应,一旦超过时间会结束会话,在该过程中调用方一直在等待响应方处理完成并返回。同步类似电话沟通,需要实时对话,异步则类似短信交流,发送消息之后无需保持等待状态。

2、异步处理优点

虽然异步处理不能实时响应,但是处理复杂业务场景,多数情况都会使用异步处理。

异步可以解耦业务间的流程关联,降低耦合度;

降低接口响应时间,例如用户注册,异步生成相关信息表;

异步可以提高系统性能,提升吞吐量;

流量削峰即把请求先承接下来,然后在异步处理;

异步用在不同服务间,可以隔离服务,避免雪崩;

异步处理的实现方式有很多种,常见多线程,消息中间件,发布订阅的广播模式,其根据逻辑在于先把请求承接下来,放入容器中,在从容器中把请求取出,统一调度处理。

注意:一定要监控任务是否产生积压过度情况,任务如果积压到雪崩之势的地步,你会感觉每一片雪花都想勇闯天涯。

3、异步处理模式

异步流程处理的实现有好多方式,但是实际开发中常用的就那么几种,例如:

基于接口异步响应,常用在第三方对接流程;

基于消息生产和消费模式,解耦复杂流程;

基于发布和订阅的广播模式,常见系统通知

异步适用的业务场景,对数据强一致性的要求不高,异步处理的

java 异步调用方法

1. 使用wait和notify方法

这个方法其实是利用了锁机制,直接贴代码:

public class Demo1 extends BaseDemo{ private final Object lock = new Object(); @Override public void callback(long response) { System.out.println("得到结果"); System.out.println(response); System.out.println("调用结束"); synchronized (lock) { lock.notifyAll(); } } public static void main(String[] args) { Demo1 demo1 = new Demo1(); demo1.call(); synchronized (demo1.lock){ try { demo1.lock.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println("主线程内容"); } }

可以看到在发起调用后,主线程利用wait进行阻塞,等待回调中调用notify或者notifyAll方法来进行唤醒。注意,和大家认知的一样,这里wait和notify都是需要先获得对象的锁的。在主线程中最后我们打印了一个内容,这也是用来验证实验结果的,如果没有wait和notify,主线程内容会紧随调用内容立刻打印;而像我们上面的代码,主线程内容会一直等待回调函数调用结束才会进行打印。

没有使用同步操作的情况下,打印结果:发起调用 调用返回 主线程内容 得到结果 1 调用结束

而使用了同步操作后:

发起调用 调用返回 得到结果 9 调用结束 主线程内容2. 使用条件锁

和方法一的原理类似:

public class Demo2 extends BaseDemo { private final Lock lock = new ReentrantLock(); private final Condition con = lock.newCondition(); @Override public void callback(long response) { System.out.println("得到结果"); System.out.println(response); System.out.println("调用结束"); lock.lock(); try { con.signal(); }finally { lock.unlock(); } } public static void main(String[] args) { Demo2 demo2 = new Demo2(); demo2.call(); demo2.lock.lock(); try { demo2.con.await(); } catch (InterruptedException e) { e.printStackTrace(); }finally { demo2.lock.unlock(); } System.out.println("主线程内容"); } }

基本上和方法一没什么区别,只是这里使用了条件锁,两者的锁机制有所不同。

JAVA里面方法回调是什么意思?

所谓回调,就是客户程序C调用服务程序S中的某个函数A,然后S又在某个时候反过来调用C中的某个函数B,对于C来说,这个B便叫做回调函数。例如Win32下的窗口过程函数就是一个典型的回调函数。一般说来,C不会自己调用B,C提供B的目的就是让S来调用它,而且是C不得不提供。由于S并不知道C提供的B姓甚名谁,所以S会约定B的接口规范(函数原型),然后由C提前通过S的一个函数R告诉S自己将要使用B函数,这个过程称为回调函数的注册,R称为注册函数。Web Service以及Java的RMI都用到回调机制,可以访问远程服务器程序。\x0d\x0a\x0d\x0a下面举个通俗的例子:\x0d\x0a某天,我打电话向你请教问题,当然是个难题,^_^,你一时想不出解决方法,我又不能拿着电话在那里傻等,于是我们约定:等你想出办法后打手机通知我,这样,我就挂掉电话办其它事情去了。过了XX分钟,我的手机响了,你兴高采烈的说问题已经搞定,应该如此这般处理。故事到此结束。这个例子说明了“异步+回调”的编程模式。其中,你后来打手机告诉我结果便是一个“回调”过程;我的手机号码必须在以前告诉你,这便是注册回调函数;我的手机号码应该有效并且手机能够接收到你的呼叫,这是回调函数必须符合接口规范。\x0d\x0a\x0d\x0a通过上面个人感觉到回调更多的应用就是结合异步。比如:Ajax中js通过组件和服务器的异步通信。

关于java异步回调解决方案和java异步处理方法的介绍到此就结束了,不知道你从中找到你需要的信息了吗 ?如果你还想了解更多这方面的信息,记得收藏关注本站。