Rumah Java javaTutorial 常见JAVA中IO/NIO模型

常见JAVA中IO/NIO模型

Aug 23, 2019 pm 03:39 PM
java

我们常见的IO模型有:阻塞 IO 模型、非阻塞 IO 模型、多路复用 IO 模型、 信号驱动 IO 模型、异步 IO 模型;下面我们就简单介绍一下以上IO模型。

常见JAVA中IO/NIO模型

1、阻塞 IO 模型

最传统的一种IO 模型,即在读写数据过程中会发生阻塞现象。当用户线程发出IO 请求之后,内核会去查看数据是否就绪,如果没有就绪就会等待数据就绪,而用户线程就会处于阻塞状态,用户线程交出CPU。当数据就绪之后,内核会将数据拷贝到用户线程,并返回结果给用户线程,用户线程才解除block 状态。典型的阻塞IO 模型的例子为:data = socket.read();如果数据没有就绪,就会一直阻塞在read 方法。

2、非阻塞 IO 模型

当用户线程发起一个read 操作后,并不需要等待,而是马上就得到了一个结果。如果结果是一个error 时,它就知道数据还没有准备好,于是它可以再次发送read 操作。一旦内核中的数据准备好了,并且又再次收到了用户线程的请求,那么它马上就将数据拷贝到了用户线程,然后返回。所以事实上,在非阻塞IO 模型中,用户线程需要不断地询问内核数据是否就绪,也就说非阻塞IO不会交出CPU,而会一直占用CPU。典型的非阻塞IO 模型一般如下:

while(true){
        data = socket.read();
        if(data!= error){
        处理数据
        break;
    }
}

但是对于非阻塞IO 就有一个非常严重的问题,在while 循环中需要不断地去询问内核数据是否就绪,这样会导致CPU 占用率非常高,因此一般情况下很少使用while 循环这种方式来读取数据。

3、多路复用 IO 模型

多路复用IO 模型是目前使用得比较多的模型。

Java NIO 实际上就是多路复用IO。在多路复用IO模型中,会有一个线程不断去轮询多个socket 的状态,只有当socket 真正有读写事件时,才真正调用实际的IO 读写操作。

因为在多路复用IO 模型中,只需要使用一个线程就可以管理多个socket,系统不需要建立新的进程或者线程,也不必维护这些线程和进程,并且只有在真正有socket 读写事件进行时,才会使用IO 资源,所以它大大减少了资源占用。

在Java NIO 中,是通过selector.select()去查询每个通道是否有到达事件,如果没有事件,则一直阻塞在那里,因此这种方式会导致用户线程的阻塞。

多路复用IO 模式,通过一个线程就可以管理多个socket,只有当socket 真正有读写事件发生才会占用资源来进行实际的读写操作。因此,多路复用IO 比较适合连接数比较多的情况。

另外多路复用IO 为何比非阻塞IO 模型的效率高是因为在非阻塞IO 中,不断地询问socket 状态时通过用户线程去进行的,而在多路复用IO 中,轮询每个socket 状态是内核在进行的,这个效率要比用户线程要高的多。

不过要注意的是,多路复用IO 模型是通过轮询的方式来检测是否有事件到达,并且对到达的事件逐一进行响应。因此对于多路复用IO 模型来说,一旦事件响应体很大,那么就会导致后续的事件迟迟得不到处理,并且会影响新的事件轮询。

4、信号驱动 IO 模型

在信号驱动IO 模型中,当用户线程发起一个IO 请求操作,会给对应的socket 注册一个信号函数,然后用户线程会继续执行,当内核数据就绪时会发送一个信号给用户线程,用户线程接收到信号之后,便在信号函数中调用IO 读写操作来进行实际的IO 请求操作。

5、异步 IO 模型

异步IO 模型才是最理想的IO 模型,在异步IO 模型中,当用户线程发起read 操作之后,立刻就可以开始去做其它的事。

而另一方面,从内核的角度,当它受到一个asynchronous read 之后,它会立刻返回,说明read 请求已经成功发起了,因此不会对用户线程产生任何block。

然后,内核会等待数据准备完成,然后将数据拷贝到用户线程,当这一切都完成之后,内核会给用户线程发送一个信号,告诉它read 操作完成了。也就说用户线程完全不需要实际的整个IO 操作是如何进行的,只需要先发起一个请求,当接收内核返回的成功信号时表示IO 操作已经完成,可以直接去使用数据了。

也就说在异步IO 模型中,IO 操作的两个阶段都不会阻塞用户线程,这两个阶段都是由内核自动完成,然后发送一个信号告知用户线程操作已完成。用户线程中不需要再次调用IO 函数进行具体的读写。

这点是和信号驱动模型有所不同的,在信号驱动模型中,当用户线程接收到信号表示数据已经就绪,然后需要用户线程调用IO 函数进行实际的读写操作;而在异步IO 模型中,收到信号表示IO 操作已经完成,不需要再在用户线程中调用IO 函数进行实际的读写操作。

注意,异步IO 是需要操作系统的底层支持,在Java 7 中,提供了Asynchronous IO。

Atas ialah kandungan terperinci 常见JAVA中IO/NIO模型. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn

Alat AI Hot

Undress AI Tool

Undress AI Tool

Gambar buka pakaian secara percuma

Undresser.AI Undress

Undresser.AI Undress

Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover

AI Clothes Remover

Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Clothoff.io

Clothoff.io

Penyingkiran pakaian AI

Video Face Swap

Video Face Swap

Tukar muka dalam mana-mana video dengan mudah menggunakan alat tukar muka AI percuma kami!

Artikel Panas

Mejiro Ryan Build Guide | Uma Musume Pretty Derby
1 bulan yang lalu By Jack chen
Rimworld Odyssey Cara Ikan
4 minggu yang lalu By Jack chen
Apakah had transaksi untuk pengguna asing di Alipay?
1 bulan yang lalu By 下次还敢

Alat panas

Notepad++7.3.1

Notepad++7.3.1

Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina

SublimeText3 versi Cina

Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1

Hantar Studio 13.0.1

Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6

Dreamweaver CS6

Alat pembangunan web visual

SublimeText3 versi Mac

SublimeText3 versi Mac

Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

Topik panas

Tutorial PHP
1505
276
Kekunci kelantangan pada papan kekunci tidak berfungsi Kekunci kelantangan pada papan kekunci tidak berfungsi Aug 05, 2025 pm 01:54 PM

First,checkiftheFnkeysettingisinterferingbytryingboththevolumekeyaloneandFn volumekey,thentoggleFnLockwithFn Escifavailable.2.EnterBIOS/UEFIduringbootandenablefunctionkeysordisableHotkeyModetoensurevolumekeysarerecognized.3.Updateorreinstallaudiodriv

Penonton pdf tepi tidak berfungsi Penonton pdf tepi tidak berfungsi Aug 07, 2025 pm 04:36 PM

Testthepdfinanotherapptodetermineiftheisseiswiththefileoredge.2.enableTetHEBuilt-Inpdfviewerbyturningoff "AlwaysopenpdffileseXternally" dan "muat turun" inedgesettings.3.clearbrowsdataincludingcookiesandcookiescookiesandcookiescookiesandcookiescookieshincookieshincookiescookiescookiescookiescookiescookiescookiescookiescookiescokiescookiescookiescookiescookiescookiescooker

Python Logging to File Contoh Python Logging to File Contoh Aug 04, 2025 pm 01:37 PM

Modul pembalakan Python boleh menulis log ke fail melalui FileHandler. Pertama, hubungi pemproses dan format fail konfigurasi BasicConfig, seperti menetapkan tahap ke maklumat, menggunakan FileHandler untuk menulis app.log; Kedua, tambah StreamHandler untuk mencapai output ke konsol pada masa yang sama; Senario lanjutan boleh menggunakan timedrotatingfilehandler untuk membahagikan log mengikut masa, sebagai contoh, menetapkan apabila = 'tengah malam' untuk menghasilkan fail baru setiap hari dan menyimpan 7 hari sandaran, dan pastikan bahawa direktori log wujud; Adalah disyorkan untuk menggunakan getLogger (__ name__) untuk membuat pembalak bernama, dan menghasilkan

Bagaimana untuk menyertai pelbagai rentetan di Jawa? Bagaimana untuk menyertai pelbagai rentetan di Jawa? Aug 04, 2025 pm 12:55 PM

Menggunakan string.join () (java8) adalah kaedah yang paling mudah disyorkan untuk menyambungkan tatasusunan rentetan, hanya tentukan pemisah secara langsung; 2. Untuk versi lama Java atau apabila lebih banyak kawalan diperlukan, anda boleh menggunakan StringBuilder untuk secara manual melintasi dan bersembunyi; 3. Stringjoiner sesuai untuk senario yang memerlukan format yang lebih fleksibel seperti awalan dan akhiran; 4. Menggunakan Arrays.Stream () digabungkan dengan pengumpul.joining () sesuai untuk penapisan atau menukar array sebelum menyertai; Untuk meringkaskan, jika Java8 dan ke atas digunakan, kaedah string.join () harus lebih disukai dalam kebanyakan kes, yang ringkas dan mudah dibaca, tetapi untuk logik yang kompleks, ia disyorkan.

Contoh Data Python Pandas Styling Contoh Contoh Data Python Pandas Styling Contoh Aug 04, 2025 pm 01:43 PM

Menggunakan Pandasstyling dalam Jupyternotebook boleh mencapai paparan DataFrame yang indah. 1. Gunakan sorotan_max dan sorotan_min untuk menyerlahkan nilai maksimum (hijau) dan nilai minimum (merah) bagi setiap lajur; 2. Tambah warna latar belakang kecerunan (seperti blues atau merah) ke lajur angka melalui latar belakang_gradient untuk memaparkan saiz data secara visual; 3. Fungsi tersuai color_score digabungkan dengan applyMap untuk menetapkan warna teks untuk selang pecahan yang berbeza (≥90 hijau, 80 ~ 89 oren, 60 ~ 79 merah,

Kaedah yang dikira vs kaedah di Vue Kaedah yang dikira vs kaedah di Vue Aug 05, 2025 am 05:21 AM

Dikira mempunyai cache, dan pelbagai akses tidak dikira semula apabila pergantungan tetap tidak berubah, sementara kaedah dilaksanakan setiap kali mereka dipanggil; 2. Komputed sesuai untuk pengiraan berdasarkan data responsif. Kaedah sesuai untuk senario di mana parameter diperlukan atau panggilan kerap tetapi hasilnya tidak bergantung kepada data responsif; 3. Kompted menyokong getters dan setters, yang dapat merealisasikan penyegerakan data dua hala, tetapi kaedah tidak disokong; 4. Ringkasan: Gunakan yang dikira terlebih dahulu untuk meningkatkan prestasi, dan menggunakan kaedah semasa lulus parameter, melakukan operasi atau mengelakkan cache, mengikuti prinsip "jika anda boleh menggunakan dikira, anda tidak menggunakan kaedah".

pergi dengan contoh menjalankan subprocess pergi dengan contoh menjalankan subprocess Aug 06, 2025 am 09:05 AM

Jalankan proses kanak -kanak menggunakan pakej OS/EXEC, buat arahan melalui exec.command tetapi tidak melaksanakannya dengan segera; 2. Jalankan arahan dengan .Output () dan tangkap stdout. Jika kod keluar bukan sifar, kembalikan exec.exiterror; 3. Gunakan .start () untuk memulakan proses tanpa menyekat, menggabungkan dengan .stDoutPipe () untuk menstrimkan output dalam masa nyata; 4. Masukkan data ke dalam proses melalui .StDinPipe (), dan selepas menulis, anda perlu menutup saluran paip dan panggilan .Wait () untuk menunggu akhir; 5. EXEC.EXITError mesti diproses untuk mendapatkan kod keluar dan stderr perintah gagal untuk mengelakkan proses zombie.

Python Cek Jika Laluan adalah Contoh Direktori Python Cek Jika Laluan adalah Contoh Direktori Aug 04, 2025 pm 02:12 PM

Kaedah yang paling biasa ialah menggunakan os.path.isdir () atau pathlib.path.is_dir (). 1. Gunakan os.path.isdir (): importos, path = "/path/to/your/direktori", ifos.path.isdir (path): cetak ("ini direktori") lain: cetak ("Ini bukan direktori atau laluan tidak wujud"). 2. Gunakan pathlib.path.is_dir () (disyorkan): daripathlibImportp

See all articles