Ketika datang ke Java Nio (input/output baru), ini adalah set API Java yang kuat yang menyediakan sistem I/O yang berorientasi buffer, tidak memblokir. Sebagai pemasok NIO, saya telah menyaksikan secara langsung berbagai kesalahan umum yang dilakukan pengembang saat menggunakan Java Nio. Dalam posting blog ini, saya akan mempelajari kesalahan -kesalahan ini dan menawarkan wawasan tentang cara menghindarinya.
1. Kesalahpahaman alam yang tidak menghalangi
Salah satu konsep paling mendasar di Java Nio adalah sifatnya yang tidak menghalangi. Namun, banyak pengembang salah paham konsep ini. Dalam I/O tradisional, operasi seperti membaca dari soket atau file memblokir, yang berarti utas ditahan sampai operasi selesai. Sebaliknya, Java Nio memungkinkan utas untuk melakukan tugas -tugas lain sambil menunggu operasi I/O selesai.
Kesalahan umum adalah menggunakan saluran non -memblokir dengan cara yang meniadakan keuntungan mereka. Misalnya, beberapa pengembang dapat menulis kode yang terus -menerus membentangkan saluran non -pemblokiran untuk memeriksa apakah data tersedia. Ini dapat menyebabkan penggunaan CPU tinggi karena utas terus berjalan dalam loop yang ketat, mengonsumsi sumber daya bahkan ketika tidak ada data baru.
impor java.nio.channels.socketchannel; impor java.io.ioException; kelas publik BadNonBlockingExample {public static void main (string [] args) melempar ioException {socketchannel channel = socketchannel.open (); channel.configureblocking (false); while (true) {if (channel.read (null)> 0) {// Proses data}}}}
Untuk menghindari kesalahan ini, pengembang harus menggunakanPemilihdi Java Nio. APemilihmemungkinkan satu utas untuk memantau beberapa saluran untuk berbagai acara sepertiOp_read,Op_write, dll. Dengan cara ini, utas dapat menunggu secara efisien sampai suatu peristiwa terjadi di salah satu saluran terdaftar.


impor java.nio.channels.socketchannel; impor java.nio.channels.elector; impor java.nio.channels.selectionKey; impor java.io.ioException; impor java.util.iterator; kelas publik goodnonblockingexample {public static void main (string [] args) melempar ioException {socketchannel channel = socketchannel.open (); channel.configureblocking (false); Selector selector = selector.open (); channel.register (selector, selectionkey.op_read); while (true) {selector.select (); Iterator <dectionKey> keys = selector.selectedKeys (). Iterator (); while (keys.hasnext ()) {selectionKey key = keys.next (); if (key.isreadable ()) {// Proses data} keys.remove (); }}}}
2. Manajemen buffer yang tidak tepat
Buffer adalah inti dari Java Nio. Mereka digunakan untuk menyimpan data yang dibaca dari saluran atau data yang akan ditulis ke saluran. Salah satu kesalahan umum adalah manajemen buffer yang tidak tepat, terutama mengenaiposisi,membatasi, Dankapasitasdari buffer.
Itukapasitasdari buffer adalah jumlah maksimum elemen yang dapat dipegangnya. Ituposisimenunjukkan lokasi saat ini di mana elemen berikutnya akan dibaca atau ditulis, danmembatasiadalah indeks setelah elemen valid terakhir.
Pengembang sering lupa untuk membalik buffer setelah menulis data ke dalamnya sebelum membaca. Itumembalik()metode mengaturmembatasike arusposisidan kemudian mengatur ulangposisike 0. Tanpa membalik buffer, operasi membaca akan dimulai dari akhir data yang baru saja ditulis, yang mengarah ke hasil yang tidak terduga.
impor java.nio.bytebuffer; kelas publik BufferManagementMistake {public static void main (string [] args) {byteBuffer buffer = byteBuffer.allocate (1024); String Data = "Halo, Java Nio!"; buffer.put (data.getBytes ()); // kesalahan: tidak memanggil flip () byte [] hasil = byte baru [buffer.capacity ()]; buffer.get (hasil); System.out.println (string baru (hasil)); }}
Cara yang benar adalah dengan meneleponmembalik()Sebelum membaca dari buffer.
impor java.nio.bytebuffer; kelas publik correctBufferManagement {public static void main (string [] args) {byteBuffer buffer = byteBuffer.allocate (1024); String Data = "Halo, Java Nio!"; buffer.put (data.getBytes ()); buffer.flip (); byte [] hasil = byte baru [buffer.remaining ()]; buffer.get (hasil); System.out.println (string baru (hasil)); }}
Kesalahan terkait lainnya adalah tidak membersihkan atau memadatkan buffer saat tidak diperlukan lagi. Gagal melakukannya dapat menyebabkan kebocoran memori, terutama dalam aplikasi yang sudah lama berjalan.
3. Mengabaikan penanganan pengecualian
Penanganan pengecualian sangat penting dalam pemrograman apa pun, dan Java nio tidak terkecuali. Namun, banyak pengembang mengabaikan penanganan pengecualian yang tepat saat bekerja dengan saluran dan pemilih Java Nio.
Saat bekerja dengan saluran jaringan, misalnya, berbagai pengecualian dapat terjadi, sepertiIoExceptionSaat ada kesalahan jaringan atauClosedchannelExceptionSaat saluran sudah ditutup. Mengabaikan pengecualian ini dapat menyebabkan masalah yang sulit - untuk - debug dalam aplikasi.
impor java.nio.channels.socketchannel; impor java.io.ioException; kelas publik NoExceptionHandling {public static void main (string [] args) {coba {socketchannel channel = socketchannel.open (); // Beberapa operasi} catch (Exception e) {// Tidak ada penanganan yang tepat}}}
Pengembang harus menangani pengecualian dengan anggun. Misalnya, jikaIoExceptionTerjadi saat membaca dari saluran, aplikasi dapat mencatat kesalahan, menutup saluran dengan benar, dan mengambil tindakan pemulihan yang sesuai.
impor java.nio.channels.socketchannel; impor java.io.ioException; impor java.util.logging.level; impor java.util.logging.logger; kelas publik ProperExceptionHandling {private static final Logger Logger = logger.getLogger (properExceptionHandling.class.getName ()); public static void main (string [] args) {coba {socketchannel channel = socketchannel.open (); // beberapa operasi} catch (ioException e) {logger.log (level.severe, "IOException terjadi:", e); // Tutup saluran dan lakukan tindakan pemulihan}}}
4. Tidak mempertimbangkan keamanan utas
Java Nio Channels dan Selector tidak selalu utas - aman. Misalnya, jika beberapa utas mencoba mendaftarkan saluran dengan pemilih secara bersamaan, itu dapat menyebabkan kondisi ras.
Pengembang perlu memastikan sinkronisasi yang tepat saat mengakses sumber daya NIO bersama. Salah satu cara untuk melakukan ini adalah dengan menggunakan kunci. Namun, penggunaan kunci yang berlebihan juga dapat menyebabkan degradasi kinerja.
impor java.nio.channels.socketchannel; impor java.nio.channels.elector; impor java.nio.channels.selectionKey; impor java.io.ioException; impor java.util.concurrent.locks.lock; impor java.util.concurrent.locks.reentrantlock; Public Class ThreadSafetyExample {private static final lock lock = baru reentrantlock (); pemilih pemilih statis swasta; public static void main (string [] args) melempar ioException {selector = selector.open (); Thread t1 = utas baru (() -> {coba {socketchannel channel = socketchannel.open (); lock.lock (); coba {channel.register (selector, selectionkey.op_read);} akhirnya {lock.unlock ();}} catch (ioException e) {e.printstack ();}}; Thread t2 = utas baru (() -> {coba {socketchannel channel = socketchannel.open (); lock.lock (); coba {channel.register (selector, selectionkey.op_read);} akhirnya {lock.unlock ();}} catch (ioException e) {e.printstack ();}}; t1.start (); t2.start (); }}
5. Menghadap skalabilitas
Java Nio dirancang untuk dapat diukur, terutama dalam aplikasi tinggi dan latensi rendah. Namun, beberapa pengembang mengabaikan skalabilitas saat merancang aplikasi mereka.
Misalnya, jika aplikasi menggunakan satu utas untuk menangani sejumlah besar saluran, itu bisa menjadi hambatan. Dalam kasus seperti itu, pengembang harus mempertimbangkan menggunakan kumpulan utas untuk mendistribusikan beban kerja di antara banyak utas.
impor java.nio.channels.socketchannel; impor java.nio.channels.elector; impor java.nio.channels.selectionKey; impor java.io.ioException; impor java.util.concurrent.executorservice; impor java.util.concurrent.Executors; Public Class ScalabilityExample {private static final int thread_pool_size = 10; Private Static Final ExecutorService Executor = Executors.newfixedThreadPool (thread_pool_size); public static void main (string [] args) melempar ioException {selector selector = selector.open (); // mendaftar saluran sementara (true) {selector.select (); untuk (kunci selection: selector.selectedKeys ()) {executor.submit (() -> {if (key.isreadable ()) {// Proses data}}); }}}}
Kesimpulan
Sebagai pemasok NIO, saya memahami pentingnya menggunakan Java Nio dengan benar. Dengan menghindari kesalahan umum ini, pengembang dapat membangun aplikasi yang lebih efisien, andal, dan dapat diskalakan. Jika Anda tertarik untuk mempelajari lebih lanjut tentang Java Nio atau mencari komponen NIO berkualitas tinggi, kami di sini untuk membantu. Kami dapat menawarkan kepada Anda saran dan solusi profesional yang disesuaikan dengan kebutuhan spesifik Anda. Apakah Anda sedang mengerjakan proyek skala kecil atau aplikasi perusahaan skala besar, keahlian kami di NIO dapat membuat perbedaan yang signifikan.
Jika Anda juga tertarik pada mobil listrik, Anda dapat memeriksaMobil listrik nio et5.
Jika Anda memiliki pertanyaan atau siap untuk memulai diskusi pengadaan, jangan ragu untuk menghubungi kami. Kami berharap dapat bekerja sama dengan Anda untuk mencapai tujuan proyek Anda.
Referensi
- "Java Nio" oleh Ron Hitchens
- Dokumentasi Oracle Java di NIO



























































