异步编程

首先说下什么是异步,什么是同步。

  • 同步是A调用了某个方法B,A会在B的执行过程中一直等待,直到被调用的方法B返回时A结束等待,并继续执行下去,这种是调用方法和被调用方法在不同的线程中运行,调用方还需要等待被调用方结束才继续执行的过程就是同步,其实也是阻塞式调用。
  • 异步是A调用B之后,直接返回,即在被调用方计算完成之前即可返回,把剩余的计算任务交给另一个线程去做,A和B两个线程是异步的,这就是非阻塞调用。那可能会疑惑,这种异步调用B的返回结果怎么告诉A呢,其实是通过回调函数或者A执行等待,直到B完成计算即可。

简单聊下我接触Java异步编程的经历,之前做Android的时候需要前台显示一个“数据正在加载......”的界面,后台去数据库里面取数据,这个时候就用到了Java异步编程,两个线程异步执行,等后台从数据库拿到数据之后,前台停止刷新,把后台结果显示在手机上,这就好比我们平时用的软件里面显示“正在支付”,“正在查询,请稍后”的道理是一样的,可见异步编程随处可见,是每个程序员都要去了解的。

异步编程需要学的知识点

结合自身的经历,说下面试过程中以及工作过程中比较常用的一些Java异步编程知识点。

1. 经常问到的异步编程的两个关键字是volatile和synchronized,从字面意思就可以看出来,volatile是保证变量的可见性(一个线程原子操作修改了一个变量之后,其他线程保证可以拿到最新的值),synchronized是保证方法的同步(这里的同步是多个线程访问这个代码块和方法时,只能有一个线程进入,等该线程执行结束之后,其他线程才能进入执行)。既然synchronized方法可以保证多个线程阻塞在方法之外,如果线程过多,锁住的方法执行时间较长,会占用过多的资源,处理不好会显著较低程序的执行效率,因此控制好并发的粒度是非常重要的;

2. 其次,刚刚谈到了锁,Java里面有偏向锁,轻量级锁,重量级锁,这些锁什么时候用,Java虚拟机底层是怎么控制的。这些锁的思想其实与我们使用数据库时加的锁是一致的,我们需要在线程安全和线程等待时间做好控制;

3. Java线程除了单独创建以外,一般是要交给线程池去管理,这样能够灵活有效的使用多线程编程,那么线程池里面的参数都有哪些含义,当线程池中的线程不足以处理当前任务时我们需要采取哪些策略去解决,以及不同场景如何选择合适的线程池都是需要去考虑和学习的;

4. 最后理解了线程的基本原理之后,业界为了实现异步编程设计了很多中间件和框架,这些中间件底层是怎么实现的,Java8语言中又推出了哪些新的特性去解决异步编程的问题,我们日常访问的淘宝等网站,参加的抢红包活动,是怎么解决IO阻塞问题的,这些都是需要进一步去思考,去体会的。