同步、异步、阻塞和非阻塞

正常情况下,我们的程序以同步非阻塞的方式在运行。但是我们的程序总会出现一些耗时操作,比如复杂的计算(找出1到10亿之间的素数)和程序本身无法控制的操作(IO操作、网络请求)。包含这些耗时操作的方法我们可以把它称为阻塞方法,包含这些耗时操作的任务我们可以把它称为阻塞任务。阻塞与非阻塞是以是否耗时来定义的。

如果程序中存在大量阻塞操作,就会影响程序性能。但是阻塞的存在是客观事实,我们的程序是无法改变它的,一个网络请求需要3秒才能响应,我们不可能让它1毫秒就能响应,因为接受请求的服务器可能完全不由我们控制。但是我们可以改变处理阻塞的方式——以异步的方式处理阻塞任务。实现异步的主要技术就是多线程。图示:

同步和异步是个时序概念。同步就是同时只执行一个任务,而异步则是同时执行多个任务。

代码示例

模拟网络请求:

[java] view plain copy
 
 print?
  1. package com.zzj.asyn;  
  2.   
  3. public class HttpRequest {  
  4.     private Callable callable;  
  5.       
  6.     public HttpRequest(Callable callable) {  
  7.         this.callable = callable;  
  8.     }  
  9.       
  10.     public void send(){  
  11.         // 模拟网络请求  
  12.         try {  
  13.             Thread.sleep(1000 * 5);  
  14.         } catch (InterruptedException e) {  
  15.             e.printStackTrace();  
  16.             Thread.currentThread().interrupt();  
  17.         }  
  18.         // 回调  
  19.         this.callable.call("Hello world!");  
  20.     }  
  21.       
  22.     public interface Callable{  
  23.         void call(String result);  
  24.     }  
  25. }  

以同步方式处理阻塞任务:

[java] view plain copy
 
 print?
  1. package com.zzj.asyn;  
  2.   
  3. import com.zzj.asyn.HttpRequest.Callable;  
  4.   
  5. /** 
  6.  * 以同步的方式处理阻塞任务 
  7.  * @author lenovo 
  8.  * 
  9.  */  
  10. public class App {  
  11.     public static void main(String[] args) {  
  12.         new HttpRequest(new Callable() {  
  13.             @Override  
  14.             public void call(String result) {  
  15.                 System.out.println("Thread:" + Thread.currentThread().getName());  
  16.                 System.out.println("Message from remote server:" + result);  
  17.             }  
  18.         }).send();  
  19.         System.out.println("Thread " + Thread.currentThread().getName() + " is over!");  
  20.     }  
  21. }  

结果:

[plain] view plain copy
 
 print?
  1. Thread:main  
  2. Message from remote server:Hello world!  
  3. Thread main is over!  

 

 

以异步的方式处理阻塞任务:

[java] view plain copy
 
 print?
  1. package com.zzj.asyn;  
  2.   
  3. import com.zzj.asyn.HttpRequest.Callable;  
  4.   
  5. /** 
  6.  * 以异步的方式处理阻塞任务 
  7.  * @author lenovo 
  8.  * 
  9.  */  
  10. public class App2 {  
  11.     public static void main(String[] args) {  
  12.         new Thread(new Runnable() {  
  13.             @Override  
  14.             public void run() {  
  15.                 new HttpRequest(new Callable() {  
  16.                     @Override  
  17.                     public void call(String result) {  
  18.                         System.out.println("Thread:" + Thread.currentThread().getName());  
  19.                         System.out.println("Message from remote server:" + result);  
  20.                     }  
  21.                 }).send();  
  22.             }  
  23.         }).start();  
  24.         System.out.println("Thread " + Thread.currentThread().getName() + " is over!");  
  25.     }  
  26. }  

结果:

[plain] view plain copy
 
 print?
  1. Thread main is over!  
  2. Thread:Thread-0  
  3. Message from remote server:Hello world!  
posted @ 2017-06-05 21:18  天涯海角路  阅读(138)  评论(0)    收藏  举报