三、阻塞/非阻塞、同步/异步理解

这里先定义两个方法funcA和funcB,funcA中将调用funcB,以下我们假设funcB中做了一些耗时的IO操作。

public void funcA() {
    // 调用funcB
    funcB();
}
public void funcB() {
    // TODO: 2019/1/4 doSth
}

先了解一下内核态和用户态。计算机在调用层上划分了用户态、内核态。

我们编写的应用程序即运行在用户态,与内核态相对隔离。当我们的应用程序发起一个IO操作的时候,会通过API系统调用内核态执行内核操作。

我们可以简单理解为:应用程序的线程调用了系统的API接口,从而在内核中执行了另一个线程执行IO操作。

当执行内核调用的时候,应用程序的线程通常会停止执行,这时候进入了“阻塞”状态。进入阻塞状态的线程不能做任何操作,它得等待内核调用完成。

可是线程如何知道内核调用有没有完成呢?

1、线程一直阻塞,等到内核调用返回结果,即“同步”等待结果。 ---- 阻塞同步

2、线程一直阻塞,等待内核调用通知其已就绪,线程再去获取结果即“异步”等待通知。 ---- 阻塞异步

阻塞的方式使得线程在阻塞期间完全不能做其它事情。于是我们希望在内核调用的执行期间,线程可以继续执行以提高利用率,这种状态即“非阻塞”状态。

非阻塞状态下线程可以继续执行:

1、如果你不断地去轮询内核调用的执行结果,那么即“同步”;---- 非阻塞同步

2、如果你去做了别的事,等到内核调用结束,通知线程的时候才继续执行,即“异步。---- 非阻塞异步

总结:

同步、异步是关注于是主动获取结果,还是被动等通知。阻塞、非阻塞是关注于你是否能继续执行。

 

posted @ 2019-01-04 14:16  __lay  阅读(248)  评论(0编辑  收藏  举报