上篇文章介绍了堆外内存DirectByteBuffer,我们知道了DirectByteBuffer是分配在JVM堆外的ByteBuffer,这篇文章来了解堆内内存HeapByteBuffer。HeapByteBufferHeapByteBuffer,即分配在JVM中的heap堆中的ByteBuffer,调用ByteBuffer#allocate()即可生成一个HeapByteBuffer对象。publicstaticByteBufferallocate(intcapacity){if(capacity<0)thrownewIllegalArgumentException();return
前面9篇文章我们已经深入了解了NIO的基本概念和核心原理,想必小伙伴们对NIO的三大组件已经了然于心了,对于ByteBuffer而言,其实还有两个较为特殊的类DirectByteBuffer和MappedByteBuffer没有分析,这两个类的原理都是基于内存文件映射的。ByteBuffer分为两种,一种是直接的,另外一种是间接的。直接缓冲:直接使用内存映射,对于Java而言就是直接在JVM之外分配虚拟内存地址空间,Java中使用DirectByteBuffer来实现,也就是堆外内存。间接缓冲:是在JVM堆上实现,Java中使用HeapByteBuffer来实现,也就是堆内内存。我们这篇文章主
多线程架构前面所有文章的示例服务端都是单线程模式,这种模式存在很多的缺陷无法充分利用多核CPU的性能如果服务端某个读写操作耗时较多,则会拖慢整个服务端所以,这篇文章大明哥将介绍服务端多线程的模式,让我们榨干服务器性能。我们清楚服务端主要做两件事,建立连接和处理读写事件,所以我们可以将服务端的线程分为两组:一个线程专门处理accept事件,我们称之为Boss线程CPU核心数个线程,这些线程处理读写事件,我们称之为Worker线程这个时候,客户端服务端的关系如下:Boss线程只服务处理Acept事件,Worker线程只处理读写事件,他们都各自维护一个Selector,每个Selector负责监听自
背景我们先看下面一段代码。publicstaticvoidmain(String[]args)throwsException{ServerSocketChannelserverSocketChannel=ServerSocketChannel.open();serverSocketChannel.configureBlocking(false);serverSocketChannel.bind(newInetSocketAddress(8081));Selectorselector=Selector.open();serverSocketChannel.register(selector,Se
上篇文章(【死磕NIO】—详解Selector)详细介绍了Selector的核心原理和使用方法,这篇文章我们来深入了解Selector的源码,主要讲三个最常用的方法open(),register()和selector()。open()调用Selector.open()方法会创建一个Selector实例。publicstaticSelectoropen()throwsIOException{returnSelectorProvider.provider().openSelector();}SelectorProvider是一个抽象类,它提供了创建Selector、ServerSocketChan
前面4篇文章深入分析了NIO三大组件中的两个:Buffer和Channel:【死磕NIO】—深入分析Buffer【死磕NIO】—深入分析Channel和FileChannel【死磕NIO】—跨进程文件锁:FileLock【死磕NIO】—探索SocketChannel的核心原理这篇文章则介绍第三个组件:Selector。相比Buffer和Channel而言,Selector对于NIO来说显得更加重要,因为它是NIO实现多路复用的核心,它的使命就是完成IO的多路复用。Selector简介在前一篇文章:【死磕NIO】—ServerSocketChannel的应用实例,大明哥分析了ServerSock
上篇文章大明哥介绍了SocketChannel的核心原理及其源码,这篇文章就来介绍如何使用ServerSocketChannel,分析单独使用ServerSocketChannel存在哪些问题。阻塞模式我们先看服务端方法:publicstaticvoidmain(String[]args)throwsException{ByteBufferbuffer=ByteBuffer.allocate(100);ServerSocketChannelserverSocket=ServerSocketChannel.open()serverSocket.bind(newInetSocketAddress(
前两篇文章我们分析了Channel及FileChannel,这篇文章我们探究SocketChannel的核心原理,毕竟下一个系列就是**【死磕Netty】**了。聊聊Socket要想掌握SocketChannel,我们就必须先了解什么是Socket。要想解释清楚Socket,就需要了解下TCP/IP。注:本文重点在SocketChannel,所以对TCP和Socket仅仅只做相关介绍,有兴趣的同学,麻烦自查专业资料。TCP/IP体系结构学过计算机网络的小伙伴知道,计算机网络是分层的,每层专注于一类事情。OSI网路模型分为七层,如下:OSI模型是理论中的模型,在实际应用中我们使用的是TCP/IP
上篇文章(【死磕NIO】—深入分析Channel和FileChannel)已经详细介绍了FileChannel的核心原理及相关API,了解了FileChannel是用来读写和映射一个系统文件的Channel,其实他还有很牛逼的功能就是:跨进程文件锁。说一个场景有多个进程同时操作某一个文件,并行往文件中写数据,请问如何保证写入文件的内容是正确的?可能有小伙伴说加分布式锁,可以解决问题,但是有点儿重了。有没有更加轻量级的方案呢?多进程文件锁:FileLock。FileLockFileLock是文件锁,它能保证同一时间只有一个进程(程序)能够修改它,或者都只可以读,这样就解决了多进程间的同步文件,保
大家好,我是大明哥,这次我们来看看NIO的第二个组件:Channel。上篇文章[【死磕NIO】—深入分析Buffer]介绍了NIO中的Buffer,Buffer我们可以认为他是装载数据的容器,有了容器,还需要传输数据的通道才能完成数据的传输,这个通道就是今天要介绍的Channel。Channel我们可以认为它是本地I/O设备、网络I/O的通信桥梁,只有搭建了这座桥梁,数据才能被写入Buffer。Channel在NIO中,Channel和Buffer是相辅相成的,我们只能从Channel读取数据到Buffer中,或者从Buffer写入数据到Channle,如下图:Channel类似于OIO中的流
大家好,我是大明哥,今天我们来看看Buffer。上面几篇文章详细介绍了IO相关的一些基本概念,如阻塞、非阻塞、同步、异步的区别,Reactor模式、Proactor模式。以下是这几篇文章的链接,有兴趣的同学可以阅读下:【死磕NIO】—阻塞、非阻塞、同步、异步,傻傻分不清楚【死磕NIO】—阻塞IO,非阻塞IO,IO复用,信号驱动IO,异步IO,这你真的分的清楚吗?【死磕NIO】—Reactor模式就一定意味着高性能吗?【死磕NIO】—Proactor模式是什么?很牛逼吗?从这篇文章开始,我们将回归NIO方面的相关知识,首先从NIO的三大核心组件说起。BufferChannelSelector首先
Netty是基于JavaNIO封装的网络通讯框架,只有充分理解了JavaNIO才能理解好Netty的底层设计。JavaNIO由三个核心组件组件:BufferChannelSelector缓冲区BufferBuffer是一个数据对象,我们可以把它理解为固定数量的数据的容器,它包含一些要写入或者读出的数据。在JavaNIO中,任何时候访问NIO中的数据,都需要通过缓冲区(Buffer)进行操作。读取数据时,直接从缓冲区中读取,写入数据时,写入至缓冲区。NIO最常用的缓冲区则是ByteBuffer。下图是Buffer继承关系图:每一个Java基本类型都对应着一种Buffer,他们都包含这相同的操作,
上篇文章我们分析了高性能IO模型Reactor模式,了解了什么是Reactor模式以及它的三种常见的模式,这篇文章,大明再介绍另外一种高性能IO模型:Proactor。为什么是Proactor模式上篇文章【死磕NIO】—Reactor模式就一定意味着高性能吗?大明哥分析了Reactor模式,我们知道Reactor性能确实非常高,适合高并发场景,但是它依然存在一个问题,那就是它是同步IO。同步IO会有一个什么问题呢?同步IO需要线程自己等待内核准备好数据,在内核准备数据的过程中,当前线程是阻塞的,这样就会导致如果某个线程因为读取IO的时间过长(比如读取文件、写文件),则它势必会影响其他线程的执行
大家好,我是大明哥,我又来了。为什么是Reactor一般所有的网络服务,一般分为如下几个步骤:读请求(readrequest)读解析(readdecode)处理程序(processservice)应答编码(encodereply)发送应答(sendreply)接下来,大明哥就来分析解决这个问题的最佳实践。单线程模式对于很多小伙伴来说,最简单,最传统的方式就是一个方法来处理所有的请求,这种实现方式最简单,也是最保险的方式。这种方式实现起来虽然简单,但是性能不行,如果其中有一个请求因为某种原因阻塞了,则他后面的所有请求都会阻塞在那里,同时他也没法利用多CPU的性能,性能严重不足。多线程模式单线程的
通过上篇文章(【死磕NIO】—阻塞、非阻塞、同步、异步,傻傻分不清楚),我想你应该能够区分了什么是阻塞、非阻塞、异步、非异步了,这篇文章我们来彻底弄清楚什么是阻塞IO,非阻塞IO,IO复用,信号驱动IO,异步IO。要想彻底弄清楚这五种IO模型,我们需要先弄清楚几个基本概念。基本概念什么是IO什么是IO?维基百科上面是这样解释的:I/O(英语:Input/Output),即输入/输出,通常指数据在存储器(内部和外部)或其他周边设备之间的输入和输出,是信息处理系统(例如计算机)与外部世界(可能是人类或另一信息处理系统)之间的通信。输入是系统接收的信号或数据,输出则是从其发送的信号或数据。这是IO一
万事从最基本的开始。要想完全掌握NIO,并不是掌握上面文章(【死磕NIO】—NIO基础详解)中的三大组件就可以了,我们还需要掌握一些基本概念,如什么是IO,5种IO模型的区别,什么是阻塞&非阻塞等等,只有掌握了这些基本概念,我们对NIO才能理解得更加得心应手。这篇文章我们就从阻塞&非阻塞,同步&异步说起。同步与异步什么是同步与异步呢?百度百科是这样定义的:同步指两个或两个以上随时间变化的量在变化过程中保持一定的相对关系。异步与同步相对(这解释让我无言相对)所以,我们需要明确的是**同步与异步针对的是两个或者两个以上的事物**。对于同步而言,一个任务(调用者)的完成需要依