切记【阻塞/非阻塞】【FutureTask异步执行】

简介: 切记【阻塞/非阻塞】【FutureTask异步执行】

一、阻塞非阻塞


1.1 同步阻塞IO


在Java应用中,默认情况下所有的Socket连接的IO都是同步阻塞的

例如在java发起的一个socket的read操作大致流程如下:

1.Java启动io的read读操作开始,用户线程就进入阻塞状态

2.系统接收到read调用,开始准备数据,如果内核数据没有准备好,则内核进行等待。

3.内核一直等待完整的数据到达,就会将数据从内核缓冲区复制到用户缓冲区,返回内核结果.

4.内核返会结果后,用户线程才会解除阻塞的状态,重新运行。

特点:在内核执行IO两个点阶段,用户线程都被阻塞了。

优点:开发程序简单,阻塞期间,用户线程不占用CPU。

缺点:每个连接配备独立的线程,高并发场景下,需要大量的线程维护网络连接,内存,线程切换开销会非常大。


1.2 同步非阻塞NIO


1.内核中没有数据,系统会直接返回调用失败的结果,用户线程需要不断地发起IO调用。

2.内核中有数据,发生阻塞,知道数据从内核中复制到用户线程中,复制完成后,系统调用返回成功,解除阻塞状态,用户空间进行处理。

特点:用户线程需要不断的轮询IO系统调用,轮询数据是否已经准备好。

优点:每次发起IO调用,可以立马反悔一个结果,用户线程不会阻塞,实时性较好。

缺点:不断轮询,占用CPU,效率低下。


二、同步、异步


同步方法调用一旦开始,调用者必须等到方法调用返回后,才能继续后续的行为。

异步方法调用更像一个消息传递,一旦开始,方法调用就会立即返回,调用者就可以继续后续的操作。而,异步方法通常会在另外一个线程中,“真实”地执行着。整个过程,不会阻碍调用者的工作.


三、FutureTask结合Callable接口创建线程【异步】


Future是JDK用于处理多线程环境下异步问题的一种模式,FutureTask就是Future的一种实现。

他最大的好处就是:客户端发出请求后,可以立马得到一个返回结果,而不用一直等待这服务器来处理。

在Callable接口中,call()方法有一个类型的泛型返回值,返回值可以是任意类型,就可以通过FutureTask的get()方法来接受返回值。get方法是一个闭锁式的阻塞方法,此方法会一直等待,知道call方法执行完毕return返回值为止。


例如:Callable创建线程计算 1-100之和并返回个Main线程的sum变量:


public class CallableTest {
    public static void main(String[] args) {
        MyCallableThread thread = new MyCallableThread();
        FutureTask<Integer> task = new FutureTask<>(thread);
        new Thread(task).start();
        try {
            Integer sum = task.get();
            System.out.println(sum);
        }catch (Exception e){
        }
    }
}
class MyCallableThread implements Callable<Integer>{
    @Override
    public Integer call() throws Exception {
        System.out.println("线程开始计算 1 + ... +100");
        int sum = 0;
        for (int i = 1; i <=100; i++) {
            sum =sum + i;
        }
        return sum;
    }
}


目录
相关文章
|
7月前
|
API iOS开发
彻底搞懂同步与异步,阻塞/非阻塞
彻底搞懂同步与异步,阻塞/非阻塞
1721 0
【多线程面试题十一】、如何实现子线程先执行,主线程再执行?
要实现子线程先执行,主线程再执行,可以在启动子线程后立即调用其join()方法,使主线程等待子线程执行完成。
|
7月前
|
Java
主线程等待子线程执行完毕再执行的几种方式
主线程等待子线程执行完毕再执行的几种方式
147 0
|
7月前
|
Java
使用线程池异步执行
使用线程池异步执行
39 0
主线程等待子线程执行完毕再执行方法
主线程等待子线程执行完毕再执行方法
192 0
|
Java
【java】主线程等待子线程执行结束后再执行,线程池
【java】主线程等待子线程执行结束后再执行,线程池
189 0
阻塞式/非阻塞式与同步/异步的区别
阻塞式/非阻塞式与同步/异步的区别
96 0
【C++11】C++多线程之条件变量,异步启动任务(1)
【C++11】C++多线程之条件变量,异步启动任务(1)
140 0
理解阻塞、非阻塞与同步、异步的区别
理解阻塞、非阻塞与同步、异步的区别
理解阻塞、非阻塞与同步、异步的区别
阻塞/阻塞/同步/异步
咱就说有没有一种可能,同步、异步、阻塞、非阻塞,这几个关键词拆开看都感觉挺明白的。但是同步阻塞、同步非阻塞、异步阻塞、异步非阻塞,这几个关键词组装起来,看起来就有点那么晦涩了。这个在日常八股中经常出现字眼,其背后对应的到底是个什么样的逻辑?我们来一起揭开它那不那么神秘的面纱。/手动狗头。
120 0
阻塞/阻塞/同步/异步