当前位置: 首页 > news >正文

松江网站开发广州哪里学网络营销比较好

松江网站开发,广州哪里学网络营销比较好,wordpress 图片路径加密,网络小说写作网站文章转载自#xff1a;JavaGuide 目录BIO,NIO,AIO 总结同步与异步阻塞和非阻塞1. BIO (Blocking I/O)1.1 传统 BIO1.2 伪异步 IO1.3 代码示例1.4 总结2. NIO (New I/O)2.1 NIO 简介2.2 NIO的特性/NIO与IO区别2.3 NIO 读数据和写数据方式2.4 NIO核心组件简单介绍2.5 代码示例3.…文章转载自JavaGuide 目录BIO,NIO,AIO 总结同步与异步阻塞和非阻塞1. BIO (Blocking I/O)1.1 传统 BIO1.2 伪异步 IO1.3 代码示例1.4 总结2. NIO (New I/O)2.1 NIO 简介2.2 NIO的特性/NIO与IO区别2.3 NIO 读数据和写数据方式2.4 NIO核心组件简单介绍2.5 代码示例3. AIO (Asynchronous I/O)BIO,NIO,AIO 总结 Java 中的 BIO、NIO和 AIO 理解为是 Java 语言对操作系统的各种 IO 模型的封装。程序员在使用这些 API 的时候不需要关心操作系统层面的知识也不需要根据不同操作系统编写不同的代码。只需要使用Java的API就可以了。 在讲 BIO,NIO,AIO 之前先来回顾一下这样几个概念同步与异步阻塞与非阻塞。 同步与异步 同步 同步就是发起一个调用后被调用者未处理完请求之前调用不返回。即调用者需要等待方法返回 异步 异步就是发起一个调用后立刻得到被调用者的回应表示已接收到请求但是被调用者并没有返回结果此时我们可以处理其他的请求被调用者通常依靠事件回调等机制来通知调用者其返回结果。调用者不需要等待方法返回 同步和异步的区别最大在于异步的话调用者不需要等待处理结果被调用者会通过回调等机制来通知调用者其返回结果。 阻塞和非阻塞 阻塞 阻塞就是发起一个请求调用者一直等待请求结果返回也就是当前线程会被挂起无法从事其他任务只有当条件就绪才能继续。方法没有处理完不会返回 非阻塞 非阻塞就是发起一个请求调用者不用一直等着结果返回可以先去干其他事情。方法被调用后立即返回 那么同步阻塞、同步非阻塞和异步非阻塞又代表什么意思呢 举个生活中简单的例子你妈妈让你烧水小时候你比较笨啊在哪里傻等着水开同步阻塞。等你稍微再长大一点你知道每次烧水的空隙可以去干点其他事然后只需要时不时来看看水开了没有同步非阻塞。后来你们家用上了水开了会发出声音的壶这样你就只需要听到响声后就知道水开了在这期间你可以随便干自己的事情你需要去倒水了异步非阻塞。 总结同步和异步强调通信机制是否需要等待结果返回。阻塞和非阻塞强调线程的状态是否需要挂起。 1. BIO (Blocking I/O) 同步阻塞I/O模式数据的读取写入必须阻塞在一个线程内等待其完成。 1.1 传统 BIO BIO通信一请求一应答模型图如下(图源网络原出处不明) 采用 BIO 通信模型 的服务端通常由一个独立的 Acceptor 线程负责监听客户端的连接。我们一般通过在 while(true) 循环中服务端会调用 accept() 方法等待接收客户端的连接的方式监听请求请求一旦接收到一个连接请求就可以建立通信套接字在这个通信套接字上进行读写操作此时不能再接收其他客户端连接请求只能等待同当前连接的客户端的操作执行完成 不过可以通过多线程来支持多个客户端的连接如上图所示。 如果要让 BIO 通信模型 能够同时处理多个客户端请求就必须使用多线程主要原因是 socket.accept()、 socket.read()、 socket.write() 涉及的三个主要函数都是同步阻塞的也就是说它在接收到客户端连接请求之后为每个客户端创建一个新的线程进行链路处理处理完成之后通过输出流返回应答给客户端线程销毁。这就是典型的 一请求一应答通信模型 。我们可以设想一下如果这个连接不做任何事情的话就会造成不必要的线程开销不过可以通过 线程池机制 改善线程池还可以让线程的创建和回收成本相对较低。使用FixedThreadPool 可以有效的控制了线程的最大数量保证了系统有限的资源的控制实现了N(客户端请求数量):M(处理客户端请求的线程数量)的伪异步I/O模型N 可以远远大于 M下面一节伪异步 BIO中会详细介绍到。 我们再设想一下当客户端并发访问量增加后这种模型会出现什么问题 在 Java 虚拟机中线程是宝贵的资源线程的创建和销毁成本很高除此之外线程的切换成本也是很高的。尤其在 Linux 这样的操作系统中线程本质上就是一个进程创建和销毁线程都是重量级的系统函数。如果并发访问量增加会导致线程数急剧膨胀可能会导致线程堆栈溢出、创建新线程失败等问题最终导致进程宕机或者僵死不能对外提供服务。 1.2 伪异步 IO 为了解决同步阻塞I/O面临的一个链路需要一个线程处理的问题后来有人对它的线程模型进行了优化一一一后端通过一个线程池来处理多个客户端的请求接入形成客户端个数M线程池最大线程数N的比例关系其中M可以远远大于N.通过线程池可以灵活地调配线程资源设置线程的最大值防止由于海量并发接入导致线程耗尽。 伪异步IO模型图(图源网络原出处不明) 采用线程池和任务队列可以实现一种叫做伪异步的 I/O 通信框架它的模型图如上图所示。当有新的客户端接入时将客户端的 Socket 封装成一个Task该任务实现java.lang.Runnable接口投递到后端的线程池中进行处理JDK 的线程池维护一个消息队列和 N 个活跃线程对消息队列中的任务进行处理。由于线程池可以设置消息队列的大小和最大线程数因此它的资源占用是可控的无论多少个客户端并发访问都不会导致资源的耗尽和宕机。 伪异步I/O通信框架采用了线程池实现因此避免了为每个请求都创建一个独立线程造成的线程资源耗尽问题。不过因为它的底层任然是同步阻塞的BIO模型因此无法从根本上解决问题。 1.3 代码示例 下面代码中演示了BIO通信一请求一应答模型。我们会在客户端创建多个线程依次连接服务端并向其发送当前时间:hello world服务端会为每个客户端线程创建一个线程来处理。代码示例出自闪电侠的博客原地址如下 https://www.jianshu.com/p/a4e03835921a 客户端 /** * * author 闪电侠 * date 2018年10月14日 * Description:客户端 */public class IOClient {public static void main(String[] args) {// TODO 创建多个线程模拟多个客户端连接服务端new Thread(() - {try {Socket socket new Socket(127.0.0.1, 3333);while (true) {try {socket.getOutputStream().write((new Date() : hello world).getBytes());Thread.sleep(2000);} catch (Exception e) {}}} catch (IOException e) {}}).start();}}服务端 /** * author 闪电侠 * date 2018年10月14日 * Description: 服务端 */public class IOServer {public static void main(String[] args) throws IOException {// TODO 服务端处理客户端连接请求ServerSocket serverSocket new ServerSocket(3333);// 接收到客户端连接请求之后为每个客户端创建一个新的线程进行链路处理new Thread(() - {while (true) {try {// 阻塞方法获取新的连接Socket socket serverSocket.accept();// 每一个新的连接都创建一个线程负责读取数据new Thread(() - {try {int len;byte[] data new byte[1024];InputStream inputStream socket.getInputStream();// 按字节流方式读取数据while ((len inputStream.read(data)) ! -1) {System.out.println(new String(data, 0, len));}} catch (IOException e) {}}).start();} catch (IOException e) {}}}).start();}}1.4 总结 在活动连接数不是特别高小于单机1000的情况下这种模型是比较不错的可以让每一个连接专注于自己的 I/O 并且编程模型简单也不用过多考虑系统的过载、限流等问题。线程池本身就是一个天然的漏斗可以缓冲一些系统处理不了的连接或请求。但是当面对十万甚至百万级连接的时候传统的 BIO 模型是无能为力的。因此我们需要一种更高效的 I/O 处理模型来应对更高的并发量。 2. NIO (New I/O) 2.1 NIO 简介 NIO是一种同步非阻塞的I/O模型在Java 1.4 中引入了NIO框架对应 java.nio 包提供了 Channel , SelectorBuffer等抽象。 NIO中的N可以理解为Non-blocking不单纯是New。它支持面向缓冲的基于通道的I/O操作方法。 NIO提供了与传统BIO模型中的 Socket 和 ServerSocket 相对应的 SocketChannel 和 ServerSocketChannel 两种不同的套接字通道实现,两种通道都支持阻塞和非阻塞两种模式。阻塞模式使用就像传统中的支持一样比较简单但是性能和可靠性都不好非阻塞模式正好与之相反。对于低负载、低并发的应用程序可以使用同步阻塞I/O来提升开发速率和更好的维护性对于高负载、高并发的网络应用应使用 NIO 的非阻塞模式来开发。 2.2 NIO的特性/NIO与IO区别 如果是在面试中回答这个问题我觉得首先肯定要从 NIO 流是非阻塞 IO 而 IO 流是阻塞 IO 说起。然后可以从 NIO 的3个核心组件/特性为 NIO 带来的一些改进来分析。如果你把这些都回答上了我觉得你对于 NIO 就有了更为深入一点的认识面试官问到你这个问题你也能很轻松的回答上来了。 1)Non-blocking IO非阻塞IO IO流是阻塞的NIO流是不阻塞的。 Java NIO使我们可以进行非阻塞IO操作。比如说单线程中从通道读取数据到buffer同时可以继续做别的事情当数据读取到buffer中后线程再继续处理数据。写数据也是一样的。另外非阻塞写也是如此。一个线程请求写入一些数据到某通道但不需要等待它完全写入这个线程同时可以去做别的事情。 Java IO的各种流是阻塞的。这意味着当一个线程调用 read() 或 write() 时该线程被阻塞直到有一些数据被读取或数据完全写入。该线程在此期间不能再干任何事情了 2)Buffer(缓冲区) IO 面向流(Stream oriented)而 NIO 面向缓冲区(Buffer oriented)。 Buffer是一个对象它包含一些要写入或者要读出的数据。在NIO类库中加入Buffer对象体现了新库与原I/O的一个重要区别。在面向流的I/O中·可以将数据直接写入或者将数据直接读到 Stream 对象中。虽然 Stream 中也有 Buffer 开头的扩展类但只是流的包装类还是从流读到缓冲区而 NIO 却是直接读到 Buffer 中进行操作。 在NIO厍中所有数据都是用缓冲区处理的。在读取数据时它是直接读到缓冲区中的; 在写入数据时写入到缓冲区中。任何时候访问NIO中的数据都是通过缓冲区进行操作。 最常用的缓冲区是 ByteBuffer,一个 ByteBuffer 提供了一组功能用于操作 byte 数组。除了ByteBuffer,还有其他的一些缓冲区事实上每一种Java基本类型除了Boolean类型都对应有一种缓冲区。 3)Channel (通道) NIO 通过Channel通道 进行读写。 通道是双向的可读也可写而流的读写是单向的。无论读写通道只能和Buffer交互。因为 Buffer通道可以异步地读写。 4)Selectors(选择器) NIO有选择器而IO没有。 选择器用于使用单个线程处理多个通道。因此它需要较少的线程来处理这些通道。线程之间的切换对于操作系统来说是昂贵的。 因此为了提高系统效率选择器是有用的。 2.3 NIO 读数据和写数据方式 通常来说NIO中的所有IO都是从 Channel通道 开始的。 从通道进行数据读取 创建一个缓冲区然后请求通道读取数据。 从通道进行数据写入 创建一个缓冲区填充数据并要求通道写入数据。 数据读取和写入操作图示 2.4 NIO核心组件简单介绍 NIO 包含下面几个核心的组件 Channel(通道) Buffer(缓冲区) Selector(选择器) 整个NIO体系包含的类远远不止这三个只能说这三个是NIO体系的“核心API”。我们上面已经对这三个概念进行了基本的阐述这里就不多做解释了。 2.5 代码示例 代码示例出自闪电侠的博客原地址如下 https://www.jianshu.com/p/a4e03835921a 客户端 IOClient.java 的代码不变我们对服务端使用 NIO 进行改造。以下代码较多而且逻辑比较复杂大家看看就好。 /** * * author 闪电侠 * date 2019年2月21日 * Description: NIO 改造后的服务端 */public class NIOServer {public static void main(String[] args) throws IOException {// 1. serverSelector负责轮询是否有新的连接服务端监测到新的连接之后不再创建一个新的线程// 而是直接将新连接绑定到clientSelector上这样就不用 IO 模型中 1w 个 while 循环在死等Selector serverSelector Selector.open();// 2. clientSelector负责轮询连接是否有数据可读Selector clientSelector Selector.open();new Thread(() - {try {// 对应IO编程中服务端启动ServerSocketChannel listenerChannel ServerSocketChannel.open();listenerChannel.socket().bind(new InetSocketAddress(3333));listenerChannel.configureBlocking(false);listenerChannel.register(serverSelector, SelectionKey.OP_ACCEPT);while (true) {// 监测是否有新的连接这里的1指的是阻塞的时间为 1msif (serverSelector.select(1) 0) {SetSelectionKey set serverSelector.selectedKeys();IteratorSelectionKey keyIterator set.iterator();while (keyIterator.hasNext()) {SelectionKey key keyIterator.next();if (key.isAcceptable()) {try {// (1)// 每来一个新连接不需要创建一个线程而是直接注册到clientSelectorSocketChannel clientChannel ((ServerSocketChannel) key.channel()).accept();clientChannel.configureBlocking(false);clientChannel.register(clientSelector, SelectionKey.OP_READ);} finally {keyIterator.remove();}}}}}} catch (IOException ignored) {}}).start();new Thread(() - {try {while (true) {// (2) 批量轮询是否有哪些连接有数据可读这里的1指的是阻塞的时间为 1msif (clientSelector.select(1) 0) {SetSelectionKey set clientSelector.selectedKeys();IteratorSelectionKey keyIterator set.iterator();while (keyIterator.hasNext()) {SelectionKey key keyIterator.next();if (key.isReadable()) {try {SocketChannel clientChannel (SocketChannel) key.channel();ByteBuffer byteBuffer ByteBuffer.allocate(1024);// (3) 面向 BufferclientChannel.read(byteBuffer);byteBuffer.flip();System.out.println(Charset.defaultCharset().newDecoder().decode(byteBuffer).toString());} finally {keyIterator.remove();key.interestOps(SelectionKey.OP_READ);}}}}}} catch (IOException ignored) {}}).start();}}为什么大家都不愿意用 JDK 原生 NIO 进行开发呢从上面的代码中大家都可以看出来是真的难用除了编程复杂、编程模型难之外它还有以下让人诟病的问题 JDK 的 NIO 底层由 epoll 实现该实现饱受诟病的空轮询 bug 会导致 cpu 飙升 100% 项目庞大之后自行实现的 NIO 很容易出现各类 bug维护成本较高上面这一坨代码我都不能保证没有 bug Netty 的出现很大程度上改善了 JDK 原生 NIO 所存在的一些让人难以忍受的问题。 3. AIO (Asynchronous I/O) AIO 也就是 NIO 2。在 Java 7 中引入了 NIO 的改进版 NIO 2,它是异步非阻塞的IO模型。异步 IO 是基于事件和回调机制实现的也就是应用操作之后会直接返回不会堵塞在那里当后台处理完成操作系统会通知相应的线程进行后续的操作。 AIO 是异步IO的缩写虽然 NIO 在网络操作中提供了非阻塞的方法但是 NIO 的 IO 行为还是同步的。对于 NIO 来说我们的业务线程是在 IO 操作准备好时得到通知接着就由这个线程自行进行 IO 操作IO操作本身是同步的。除了 AIO 其他的 IO 类型都是同步的这一点可以从底层IO线程模型解释推荐一篇文章《漫话如何给女朋友解释什么是Linux的五种IO模型》 查阅网上相关资料我发现就目前来说 AIO 的应用还不是很广泛Netty 之前也尝试使用过 AIO不过又放弃了。 参考 《Netty 权威指南》第二版 https://zhuanlan.zhihu.com/p/23488863 (美团技术团队)
http://www.sadfv.cn/news/353549/

相关文章:

  • 民治营销网站名城建设有限公司网站
  • 网页设计如何换行引擎优化seo是什么
  • 天津静态管理区域网格搜索优化
  • 企业级网站开发原理图网站系统建设需要什么资质吗
  • 建设春风摩托车官方网站WordPress的数据库在哪
  • 做网站设计要多少钱用vue做多页面网站
  • 网站整合营销网站建设推广多少钱
  • 网站权重高 做别的关键词四川省住房建设厅网站
  • wordpress加速网站插件wordpress 4.5.6
  • 网站开发工具链接服务器div做网站
  • 建设网站规模与类别手机百度搜索引擎入口
  • 网站域名注册哪个好高端品牌羽绒服有哪些
  • php网站只能打开首页个人域名做邮箱网站
  • wordpress友链页面seo是什么部门
  • 网站管理规划方案七牛做网站
  • 商城网站建设哪家效益快深圳企业网站制作推广运营
  • 邢台集团网站建设桂林北站怎么去阳朔
  • 获取网站访客qq号码程序下载网站开发后如何上线
  • 乐清网站建设公司有赞网站开发
  • 有没有做翻译赚钱的网站wordpress收集
  • 学校网站建设方案设计松溪网站建设wzjseo
  • 企业网站icp备案建设银行网站最近都打不开吗
  • 黄陂区建设局网站旅游网站在提高用户体验方面应做哪些工作
  • 甜品网站模板代码网站建设好学么
  • 网站建设的注意网页制作要学什么课程
  • 安徽康东建设工程有限公司网站wordpress支付宝捐赠插件
  • 福田网站建设公司乐云seo长沙企业网站制作服务报价
  • 免费制作一个自己的网站吗电脑记事本做复杂网站
  • 企业网站有哪四种类型自由软件开发者
  • 温州市网站制作多少钱专门做二手书的网站