Java BIO改良(伪异步IO)

请先移步查看《Java 传统的BIO编程》

我们将客户端请求投递到线程池中进行处理,JDK线程池维护一个消息队列和N个活跃线程,对消息队列中的任务进行处理,由于线程池可以设置对队列的大小和最大线程数,因此占用的资源是可控的,无论多少个客户端并发访问,都不会导致资源的耗尽而宕机。

弊端分析:由于底层通信依然采用同步阻塞队列,因此无法从根本上解决问题。

Java InputStream:

public int read(byte b[]) throws IOException {

//This method blocks until input data is available, end of file is detected, or an exception is thrown.

        return read(b, 0, b.length);

    }

当对Socket输入流进行读取操作的时候,它会一直阻塞下去,直到发生下面3种事件:

(1)有数据可读

(2)可用数据已经读取完毕

(3)发生空指针或者IO异常

这就意味着当发送请求或者应答消息比较缓慢,或者网络传输缓慢时,读取输入流一方的通信线程将被长时间阻塞,如果一方要60S才能将数据读取完毕,读取一方的IO线程将会被阻塞60S,在此期间,其他消息只能在消息队列中排队。

当调用OutputStream的write方法写输出流的时候,它将会被阻塞直到所有要发送的字节全部写入完毕,或者发生异常。

伪异步IO无法从根本上解决同步IO导致的通信线程阻塞问题,下面我们分析一下通信对方返回应答时间过长会引起的级联故障。

1.服务器处理缓慢,返回应答消息耗费60S,平均只要10S

2.采用伪异步IO线程正在读取故障服务节点的响应,由于读取输入流是阻塞的,它将会被

阻塞60S

3.假设所有可用的线程都会被故障服务器阻塞,那后续的IO消息都将在队列中排队

4.由于线程池采用阻塞队列实现,当队列满了之后,后续入队列的操作将会被阻塞

5.由于前端只有一个ACCEPTOR线程接受客户端接入,它被阻塞在线程池的同步阻塞队列之后,新的客户端请求消息将会被拒绝,客户端发生大量的连接超时

6.由于几乎所有的连接都超时,调用者会认为系统已经崩溃,无法接受新的请求消息

如何,Java NIO将会给出答案!!!

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 一、多线程 说明下线程的状态 java中的线程一共有 5 种状态。 NEW:这种情况指的是,通过 New 关键字创...
    Java旅行者阅读 4,721评论 0 44
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,837评论 18 139
  • 从三月份找实习到现在,面了一些公司,挂了不少,但最终还是拿到小米、百度、阿里、京东、新浪、CVTE、乐视家的研发岗...
    时芥蓝阅读 42,341评论 11 349
  • 2018向2017挥着手说再见,接下来的日子交给我吧。于是2018踏着2017最后的尾巴,向你迎面走来。 可是20...
    HUI凡阅读 304评论 0 1
  • 如何才能实现专业发展?著名学者波斯纳提出的教师发展公式相信已为大家耳熟能详:教师的成长=经验+反思。 的确,从我们...
    龚姐姐姐姐阅读 182评论 0 0