Java 模块间调用 详解

前言

在学习Android的过程中,我们接触到不少回调 ,bindService( )成功链接触发的回调ServiceConnection.onServiceConnected( )、按键点击事件回调方法onClick( ) … 这些回调是通过什么方式实现的?是多线程吗?这些问题始值缠绕在心头。在这里捋一捋,如有理解错误的地方还望指正。

在一个应用系统中,无论使用何种语言开发,必然存在模块之间的调用,调用的方式分为几种:同步调用,异步调用,回调 1

同步调用

举个简单的例子,我们定义了一个Customer类,它有一个buybook()方法调用了Bookstore类中的getbook()方法。getbook()也很简单,直接将书库中的某本书返回即可。

这里若Customer让出CPU资源,等待getbook()执行完再继续执行下去,则我们称为阻塞;若Customer不让出资源,而是不断的轮询的getbook()的结果,则是非阻塞的。(这种情况,可以确定它们不在同一线程)
在这里插入图片描述
这种方法适用于getbook()耗时不多的情况,如果getbook()实际执行的结果是:没有该书,现在下单采购…那可的等到天荒地老呀。

这时程序就造成程序阻塞(注意区分程序阻塞与模块阻塞的区别,若是上文描述的模块非阻塞状况,则不断轮询getbook()的结果,程序同样会等到地老天荒🤷‍♂️),buybook() 中后续的代码将不能得到执行。在 Android中,若在主线程超过阀值 5s 未响应处理,则会造成ANR异常

因而在实际情况中,上面的这种非阻塞同步的用处不大,应该说一般不会用到。因为Customer不阻塞,会一直占用CPU,但是其实它只是很死脑筋地一次次地去看getbook()有没有执行完,这将会造成CPU资源严重浪费 2

那么如果非得执行较为耗时的操作,需要如何处理呢?

异步调用

异步调用是为了解决同步调用可能出现阻塞,导致整个流程“卡住”而产生的一种调用方式。

还是同步调用的🌰,只是这一次:

buybook() 方法将告诉Bookstore类:我要一本书!

Bookstore类:好的。

然后,buybook()就去干别的事情,接着执行下去了。
在这里插入图片描述
但是这样又给我们带来一个新的问题。

例如我们需要在buybook() 中使用到getbook()返回的书本对象以获取价格,才能…打钱 付款!,由于buybook() 并不会等待getbook()的执行,因而我们需要使用某些方法对getbook()进行监听,以知晓其已执行完成。

Java中,可以使用Future+Callable的方式做到这一点,具体做法可以参见
Java多线程21:多线程下其他组件之CyclicBarrier、Callable、Future和FutureTask 1

看到这可能还是会困惑,你看这个异步,又闷又… 是不是中暑了? 这个异步是怎么实现的呢?

异步的实现

最常见的方式就是多线程啦。多线程是CPU抽象出的一个概念,其本质是一段代码,采用分时等机制以维持并发,所以线程需要操作系统投入CPU资源来运行和调度。

当然异步并不是多线程的专属名称。简单来说,多线程是实现异步调用的一种方式,但却非全部。DMA就是一个不错的例子。

所谓DMA,就是直接内存访问的意思;也就是说,拥有DMA功能的硬件在和内存进行数据交换的时候可以不消耗CPU资源。只要CPU在发起数据传输时发送一个指令,硬件就开 始自己和内存交换数据,在传输完成之后硬件会触发一个中断来通知操作完成。这些无须消耗CPU时间的I/O操作可以成为异步操作的硬件基础 3

所以即使在DOS 这样的单进程(而且无线程概念)系统中也同样可以发起异步DMA操作。引进DMA可以提高处理器I/O处理器并行度 3

此外,我们开启硬件定时器也是一种异步操作,这种异步操作带着回调 – 溢出中断,以告知我们计数结果。多核CPU带来的并行处理也是一种异步操作。

总结一下我已知的异步实现:

  • 软件上:多线程
  • 硬件上:多核CPU、DMA,硬件定时器

回调

前面异步调用说到异步带来的问题,并给出了Java中解决的方法;而更常见的实现是回调。回调其实并不依赖于任何一种语言,它是一种思想,一种机制 1

还是那个🌰:

buybook() 方法将告诉Bookstore类:我要一本书!

Bookstore类:好的,你

  • 6
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值