天天看點

淺談同步異步、阻塞非阻塞

一、什麼是同步?什麼是異步?            同步就是:如果有多個任務或者事件要發生,這些任務或者事件必須逐個地進行,一個事件或者任務的執行會導緻整個流程的暫時等待,這些事件沒有辦法并發地執行;         異步就是:如果有多個任務或者事件發生,這些事件可以并發地執行,一個事件或者任務的執行不會導緻整個流程的暫時等待。           舉個簡單的例子,假如有一個任務包括兩個子任務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的執行不會導緻其後續的執行過程處于暫時的等待。 同步和異步是一個非常廣的概念,它們的重點在于多個任務和事件發生時,一個事件的發生或執行是否會導緻整個流程的暫時等待。這裡不要混淆了多線程和異步,異步隻是宏觀上的一種模式,多線程是實作異步的一種方式。

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

          阻塞就是:當某個事件或者任務在執行過程中,它發出一個請求操作,但是由于該請求操作需要的條件不滿足,那麼就會一直在那等待,直至條件滿足;         非阻塞就是:當某個事件或者任務在執行過程中,它發出一個請求操作,如果該請求操作需要的條件不滿足,會立即傳回一個标志資訊告知條件不滿足,不會一直在那等待。           也就是說阻塞和非阻塞的差別關鍵在于當送出請求一個操作時,如果條件不滿足,是會一直等待還是傳回一個标志資訊。 舉個簡單的例子:   假如我要讀取一個檔案中的内容,如果此時檔案中沒有内容可讀,對于阻塞來說就是會一直在那等待,直至檔案中有内容可讀;而對于非阻塞來說,就會直接傳回一個标志資訊告知檔案中暫時無内容可讀。    起初會把 同步和異步分别與阻塞和非阻塞畫上等号,事實上,它們是兩組完全不同的概念。

          同步和異步着重點在于多個任務的執行過程中,一個任務的執行是否會導緻整個流程的暫時等待;         而阻塞和非阻塞着重點在于發出一個請求操作時,如果進行操作的條件不滿足是否會返會一個标志資訊告知條件不滿足。     了解阻塞和非阻塞可以同線程阻塞類比地了解,當一個線程進行一個請求操作時,如果條件不滿足,則會被阻塞,即在那等待條件滿足。