天天看点

浅谈同步异步、阻塞非阻塞

一、什么是同步?什么是异步?            同步就是:如果有多个任务或者事件要发生,这些任务或者事件必须逐个地进行,一个事件或者任务的执行会导致整个流程的暂时等待,这些事件没有办法并发地执行;         异步就是:如果有多个任务或者事件发生,这些事件可以并发地执行,一个事件或者任务的执行不会导致整个流程的暂时等待。           举个简单的例子,假如有一个任务包括两个子任务A和B,对于同步来说,当A在执行的过程中,B只有等待,直至A执行完毕,B才能执行;而对于异步就是A和B可以并发地执行,B不必等待A执行完毕之后再执行,这样就不会由于A的执行导致整个任务的暂时等待。 如果还不理解,可以先看下面这2段代码:

  1. void fun1() {
  2. System.out.println("方法1");
  3. }
  4. void fun2() {
  5. System.out.println("方法2");
  6. }
  7. void function(){
  8. fun1();
  9. fun2();
  10. }

         这就是典型的同步,在方法function中,fun1在执行的过程中会导致后续的fun2无法执行,fun2必须等待fun1执行完毕才可以执行。 接着看下面这段代码:

  1. void fun1() {
  2. System.out.println("方法1");
  3. }
  4. void fun2() {
  5. System.out.println("方法2");
  6. }
  7. void function(){
  8. new Thread(){
  9. public void run() {
  10. fun1();
  11. }
  12. }.start();
  13. new Thread(){
  14. public void run() {
  15. fun2();
  16. }
  17. }.start();
  18. }

        这段代码是一种典型的异步,fun1的执行不会影响到fun2的执行,并且fun1和fun2的执行不会导致其后续的执行过程处于暂时的等待。 同步和异步是一个非常广的概念,它们的重点在于多个任务和事件发生时,一个事件的发生或执行是否会导致整个流程的暂时等待。这里不要混淆了多线程和异步,异步只是宏观上的一种模式,多线程是实现异步的一种方式。

二、什么是阻塞?什么是非阻塞?

          阻塞就是:当某个事件或者任务在执行过程中,它发出一个请求操作,但是由于该请求操作需要的条件不满足,那么就会一直在那等待,直至条件满足;         非阻塞就是:当某个事件或者任务在执行过程中,它发出一个请求操作,如果该请求操作需要的条件不满足,会立即返回一个标志信息告知条件不满足,不会一直在那等待。           也就是说阻塞和非阻塞的区别关键在于当发出请求一个操作时,如果条件不满足,是会一直等待还是返回一个标志信息。 举个简单的例子:   假如我要读取一个文件中的内容,如果此时文件中没有内容可读,对于阻塞来说就是会一直在那等待,直至文件中有内容可读;而对于非阻塞来说,就会直接返回一个标志信息告知文件中暂时无内容可读。    起初会把 同步和异步分别与阻塞和非阻塞画上等号,事实上,它们是两组完全不同的概念。

          同步和异步着重点在于多个任务的执行过程中,一个任务的执行是否会导致整个流程的暂时等待;         而阻塞和非阻塞着重点在于发出一个请求操作时,如果进行操作的条件不满足是否会返会一个标志信息告知条件不满足。     理解阻塞和非阻塞可以同线程阻塞类比地理解,当一个线程进行一个请求操作时,如果条件不满足,则会被阻塞,即在那等待条件满足。