关于nio:大话网络通信
1、术语并发 vs 并行并发和并行是相干的概念,但有一些小的区别。并发意味着两个或多个工作正在获得停顿,即便它们可能不会同时执行。例如,这能够通过工夫切片来实现,其中局部工作按程序执行,并与其余工作的局部混合。另一方面,当执行的工作能够真正同时进行时,就会呈现并行简略说启动一个线程在一个core上就是并行,启动两个线程在一个core上就是并发异步 vs 同步如果调用者在办法返回值或引发异样之前无奈获得停顿,则认为办法调用是同步的。另一方面,异步调用容许调用者在无限的步骤之后持续进行,并且能够通过一些附加机制 (它可能是已注册的回调、Future 或音讯)来告诉办法的实现简略来说Java API层来说的,如下 :ExecutorService executorService = Executors.newFixedThreadPool(2); Future<Boolean> future = executorService.submit(new Callable<Boolean>() { @Override public Boolean call() throws Exception { System.out.println("执行业务逻辑"); // 依据业务逻辑判断给定返回 return true; } }); future.get(); // 同步API,必须等到返回 if(future.isDone()) { future.get();// 异步API,只有执行完,再get后果 } 同步 API 能够应用阻塞来实现同步,但这不是必要的。CPU 密集型工作可能会产生相似 于阻塞的行为。一般来说,最好应用异步 API,因为它们保证系统可能进行非阻塞 vs 阻塞如果一个线程的提早能够无限期地提早其余一些线程,这就是咱们探讨的阻塞。一个很好的例子是,一个线程能够应用互斥来独占应用一个资源。如果一个线程无限期地占用资源(例如意外运行有限循环),则期待该资源的其余线程将无奈进行。相同,非阻塞意味着没有线程可能无限期地提早其余线程非阻塞操作优先于阻塞操作,因为当零碎蕴含阻塞操作时,零碎的总体进度并不能失去很好的保障 死锁 vs 饥饿 vs 活锁当多个线程在期待对方达到某个特定的状态以便可能获得停顿时,就会呈现死锁。因为没有其余线程达到某种状态,所有受影响的子系统都无奈持续运行。死锁与阻塞密切相关,因为线程可能无限期地提早其余线程的过程在死锁的状况下,没有线程能够获得停顿,相同,当有线程能够获得停顿,但可能有一个或多个线程不能获得停顿时,就会产生饥饿。典型的场景是一个调度算法,它总是抉择高优先级的工作而不是低优先级的工作。如果传入的高优先级工作的数量始终足够多,那么低优先级工作将永远不会实现活锁相似于死锁,因为没有线程获得停顿。不同之处在于,线程不会被解冻在期待别人停顿的状态中,而是一直地扭转本人的状态。一个示例场景是,两个线程有两个雷同资源可用时。他们每一个都试图取得资源,但他们也会查看对方是否也须要资源。 如果资源是由另一个线程申请的,他们会尝试获取该资源的另一个实例。在可怜的情 况下,两个线程可能会在两种资源之间“反弹”,从不获取资源,但总是屈服于另一种资源2、BIO vs NIOBIOserverSocket.accept(),这里会阻塞socket.getInputStream.read(),也会阻塞 尽管能够应用了线程池,因为read()办法的阻塞,其实线程池也是不能复用的,说白了,就是须要一个客户端一个线程进行服务 思考:那BIO就没有应用场景了吗?其实不是,BIO在建设长连贯的流式传输场景还是很有用的,比如说HDSF,客户端向DataNode传输数据应用的就是建设一个BIO的管道,流式上传数据的。此时引入一个问题,那HDFS DataNode就不思考到线程阻塞么?是这样的,其实要晓得你不可能多个客户端上传文件都是针对某个DataNode(NameNode会进行抉择DataNode),所以线程阻塞的压力是会摊派的。NIO还是善于小数据量的RPC申请,能承受百万客户端的连贯 NIONIO中有三个重要组件 : Buffer(ByteBuffer次要应用)、Channel(双向通道,可读可写)和Selector(多路复用选择器) Buffer罕用的就是 ByteBuffer,缓冲池,能够作为channel写的单位,也能够承受channel读取的返回外面重要的属性 :position、capacity、flip、limit和hasRemain 每个channel都须要记录可能切分的音讯,因为ByteBuffer不能被多个channel应用,因而须要为每个channel保护一个独立的ByteBuffer。ByteBuffer不能太大,比方一个ByteBuffer 1M的话,须要反对百万连贯要1TB内存,因而须要设计大小可变的ByteBuffer 1、首先调配一个较小的buffer,比方4k,如果发现不够的话,再调配8kb的buffer,将4kb buffer内容拷贝到8kb buffer,有点是音讯间断容易解决,毛病是数据拷贝消耗性能 2、多个数组组成buffer,一个数组不够,把多进去的内容写入新的数组,毛病不间断解析简单,有点防止了拷贝引起的性能损耗 ...