php的网站数据库如何上传,wordpress固定设备登录,深圳工业设计机构,网站建设合同书(范本)1、阻塞与非阻塞
阻塞与非阻塞是描述进程在访问某个资源时#xff0c;数据是否准备就绪的的一种处理方式。当数据没有准备就绪时#xff1a;
阻塞#xff1a;线程持续等待资源中数据准备完成#xff0c;直到返回响应结果。非阻塞#xff1a;线程直接返回结果#xff0c…1、阻塞与非阻塞
阻塞与非阻塞是描述进程在访问某个资源时数据是否准备就绪的的一种处理方式。当数据没有准备就绪时
阻塞线程持续等待资源中数据准备完成直到返回响应结果。非阻塞线程直接返回结果不会持续等待资源准备数据结束后才响应结果。
2、同步与异步
同步与异步是指访问数据的机制同步一般指主动请求并等待IO操作完成的方式。异步则指主动请求数据后便可以继续处理其它任务随后等待IO操作完毕的通知。
老王烧开水 1、普通水壶煮水站在旁边主动的看水开了没有同步的阻塞 2、普通水壶煮水去干点别的事每过一段时间去看看水开了没有水没开就走人。 同步非阻塞 3、响水壶煮水站在旁边不会每过一段时间主动看水开了没有。如果水开了水壶自动通知他。 异步阻塞 4、响水壶煮水去干点别的事如果水开了水壶自动通知他。异步非阻塞
基础概念
1、传统BIO模型
传统BIO是一种同步的阻塞IOIO在进行读写时该线程将被阻塞线程无法进行其它操作。 IO流在读取时会阻塞。直到发生以下情况1、有数据可以读取。2、数据读取完成。3、发生异常
2、伪异步IO模型
以传统BIO模型为基础通过线程池的方式维护所有的IO线程实现相对高效的线程开销及管理。
3、NIO模型
NIOJDK1.4模型是一种同步非阻塞IO主要有三大核心部分Channel(通道)Buffer(缓冲区), Selector多路复用器。传统IO基于字节流和字符流进行操作而NIO基于Channel和Buffer(缓冲区)进行操作数据总是从通道读取到缓冲区中或者从缓冲区写入到通道中。Selector(多路复用器)用于监听多个通道的事件比如连接打开数据到达。因此单个线程可以监听多个数据通道。 NIO和传统IO一下简称IO之间第一个最大的区别是IO是面向流的NIO是面向缓冲区的。 Java IO面向流意味着每次从流中读一个或多个字节直至读取所有字节它们没有被缓存在任何地方。此外它不能前后移动流中的数据。如果需要前后移动从流中读取的数据需要先将它缓存到一个缓冲区。NIO的缓冲导向方法略有不同。数据读取到一个它稍后处理的缓冲区需要时可在缓冲区中前后移动。这就增加了处理过程中的灵活性。但是还需要检查是否该缓冲区中包含所有您需要处理的数据。而且需确保当更多的数据读入缓冲区时不要覆盖缓冲区里尚未处理的数据。 IO的各种流是阻塞的。这意味着当一个线程调用read() 或 write()时该线程被阻塞直到有一些数据被读取或数据完全写入。该线程在此期间不能再干任何事情了。 NIO的非阻塞模式使一个线程从某通道发送请求读取数据但是它仅能得到目前可用的数据如果目前没有数据可用时就什么都不会获取。而不是保持线程阻塞所以直至数据变的可以读取之前该线程可以继续做其他的事情。 非阻塞写也是如此。一个线程请求写入一些数据到某通道但不需要等待它完全写入这个线程同时可以去做别的事情。 线程通常将非阻塞IO的空闲时间用于在其它通道上执行IO操作所以一个单独的线程现在可以管理多个输入和输出通道channel。
NIO优点
通过Channel注册到Selector上的状态来实现一种客户端与服务端的通信。Channel中数据的读取是通过Buffer , 一种非阻塞的读取方式。Selector 多路复用器 单线程模型 线程的资源开销相对比较小。
Channel(通道)
传统IO操作对read()或write()方法的调用可能会因为没有数据可读/可写而阻塞直到有数据响应。也就是说读写数据的IO调用可能会无限期的阻塞等待效率依赖网络传输的速度。最重要的是在调用一个方法前无法知道是否会被阻塞。
NIO的Channel抽象了一个重要特征就是可以通过配置它的阻塞行为来实现非阻塞式的通道。
Channel是一个双向通道与传统IO操作只允许单向的读写不同的是NIO的Channel允许在一个通道上进行读和写的操作。
FileChannel:文件
SocketChannel:
ServerSocketChannel:
DatagramChannel: UDP
Buffer(缓冲区)
Bufer顾名思义它是一个缓冲区实际上是一个容器一个连续数组。Channel提供从文件、网络读取数据的渠道但是读写的数据都必须经过Buffer。 Buffer(缓冲区)
Buffer缓冲区本质上是一块可以写入数据然后可以从中读取数据的内存。这块内存被包装成NIO Buffer对象并提供了一组方法用来方便的访问该模块内存。为了理解Buffer的工作原理需要熟悉它的三个属性capacity、position和limit。
position和limit的含义取决于Buffer处在读模式还是写模式。不管Buffer处在什么模式capacity的含义总是一样的。见下图 capacity、position和limit
capacity作为一个内存块Buffer有固定的大小值也叫作“capacity”只能往其中写入capacity个byte、long、char等类型。一旦Buffer满了需要将其清空通过读数据或者清楚数据才能继续写数据。position当你写数据到Buffer中时position表示当前的位置。出事的position值为0当写入一个字节数据到Buffer中后position会向前移动到下一个可插入数据的Buffer单元。position最大可为capacity-1。当读取数据时也是从某个特定位置读讲Buffer从写模式切换到读模式position会被重置为0。当从Buffer的position处读取一个字节数据后position向前移动到下一个可读的位置。limit在写模式下Buffer的limit表示你最多能往Buffer里写多少数据。 写模式下limit等于Buffer的capacity。当切换Buffer到读模式时 limit表示你最多能读到多少数据。因此当切换Buffer到读模式时limit会被设置成写模式下的position值。换句话说你能读到之前写入的所有数据limit被设置成已写数据的数量这个值在写模式下就是position
Buffer的分配
对Buffer对象的操作必须首先进行分配Buffer提供一个allocate(int capacity)方法分配一个指定字节大小的对象。 向Buffer中写数据写数据到Buffer中有两种方式 1.从channel写到Buffer
int bytes channel.read(buf); //将channel中的数据读取到buf中2.通过Buffer的put()方法写到Buffer
buf.put(byte); //将数据通过put()方法写入到buf中flip()方法将Buffer从写模式切换到读模式调用flip()方法会将position设置为0并将limit设置为之前的position的值。 从Buffer中读数据从Buffer中读数据有两种方式 1.从Buffer读取数据到Channel
int bytes channel.write(buf); //将buf中的数据读取到channel中2.通过Buffer的get()方法读取数据
byte bt buf.get(); //从buf中读取一个byterewind()方法Buffer.rewind()方法将position设置为0使得可以重读Buffer中的所有数据limit保持不变。clear()与compact()方法一旦读完Buffer中的数据需要让Buffer准备好再次被写入可以通过clear()或compact()方法完成。如果调用的是clear()方法position将被设置为0limit设置为capacity的值。但是Buffer并未被清空只是通过这些标记告诉我们可以从哪里开始往Buffer中写入多少数据。如果Buffer中还有一些未读的数据调用clear()方法将被遗忘 。compact()方法将所有未读的数据拷贝到Buffer起始处然后将position设置到最后一个未读元素的后面limit属性依然设置为capacity。可以使得Buffer中的未读数据还可以在后续中被使用。mark()与reset()方法通过调用Buffer.mark()方法可以标记一个特定的position之后可以通过调用Buffer.reset()恢复到这个position上。
Selector(多路复用器)
Selector与Channel是相互配合使用的将Channel注册在Selector上之后才可以正确的使用Selector但此时Channel必须为非阻塞模式。Selector可以监听Channel的四种状态Connect、Accept、Read、Write当监听到某一Channel的某个状态时才允许对Channel进行相应的操作。
Connect某一个客户端连接成功后Accept准备好进行连接Read:可读Write:可写