Nov 28, 2025

Java NIO eşzamansız G/Ç'de CompletionHandler nasıl kullanılır?

Mesaj bırakın

Selam! Bir NIO tedarikçisi olarak, Java NIO eşzamansız G/Ç dünyasının derinliklerine daldım ve bugün Java NIO eşzamansız G/Ç'de CompletionHandler'ın nasıl kullanılacağını sizinle paylaşmaktan heyecan duyuyorum. Özellikle yüksek performanslı G/Ç işlemleriyle uğraşırken, programlama oyununuzu gerçekten üst düzeye taşıyabilecek oldukça harika bir konsept.

Öncelikle Java NIO eşzamansız G/Ç'nin neyle ilgili olduğunu anlayalım. Geleneksel Java G/Ç'de işlemler engelleniyor. Bu, bir dosyadan okumak veya bir ağ soketinden veri almak gibi bir G/Ç işlemi yaptığınızda, programınızın bir sonraki göreve geçmeden önce bu işlemin bitmesini beklemesi gerektiği anlamına gelir. Bu, özellikle programınızın beklemede kalmasını istemediğiniz yüksek trafikli bir uygulamada gerçekten sıkıcı olabilir.

Java NIO asenkron I/O ise, I/O işlemi devam ederken programınızın diğer görevleri yapmaya devam etmesine olanak tanır. İşlem tamamlandığında programınıza bildirimde bulunmak için geri arama tabanlı veya geleceğe dayalı bir yaklaşım kullanır. İşte CompletionHandler'ın devreye girdiği yer burasıdır.

CompletionHandler, Java NIO'da iki yöntemi tanımlayan bir arayüzdür:tamamlanmışVearızalı.tamamlanmışasenkron G/Ç işlemi başarıyla tamamlandığında yöntem çağrılır ve işlemin sonucuna erişmenizi sağlar.arızalıİşlem sırasında bir şeyler ters giderse yöntem çağrılır ve hata hakkında bilgi verir.

Eşzamansız dosya okuma için CompletionHandler'ı kullanmanın basit bir örneğiyle başlayalım.

java.nio.ByteBuffer'ı içe aktarın; java.nio.channels.AsynchronousFileChannel'ı içe aktarın; Java.nio.channels.CompletionHandler'ı içe aktarın; java.nio.file.Path'i içe aktarın; java.nio.file.Paths'i içe aktarın; java.nio.file.StandardOpenOption'ı içe aktarın; public class AsyncFileReadExample { public static void main(String[] args) { Path path = Paths.get("test.txt"); try (AsynchronousFileChannel fileChannel = AsynchronousFileChannel.open(path, StandardOpenOption.READ)) { ByteBuffer buffer = ByteBuffer.allocate(1024); fileChannel.read(buffer, 0, buffer, new CompletionHandler<Integer, ByteBuffer>() { @Override public voidcomplete (Tamsayı sonucu, ByteBuffer eklentisi) { System.out.println("Oku " + sonuç + " bayt"); buffer.flip(); bayt[] veri = yeni bayt[buffer.limit()]; buffer.get(veri); System.out.println(yeni String(data)); } @Override public void başarısız oldu(Atılabilir exc, ByteBuffer eki) { System.err.println("Okuma başarısız oldu: " + exc.getMessage() } }); // Okuma işlemi devam ederken diğer görevleri yapın System.out.println("Diğer görevler yapılıyor..."); Thread.sleep(2000); } catch (İstisna e) { e.printStackTrace(); } } }

Bu örnekte ilk olarak bir pencere açıyoruz.EşzamansızDosya Kanalıokumak için. Sonra bir tahsis ediyoruzBayt Tamponuokuyacağımız verileri tutmak için. biz diyoruzOkumakdosya kanalındaki yöntem, ara bellekten geçme, okumaya başlanacak konum (bu durumda 0), bir ek (işlemle birlikte iletmek istediğiniz herhangi bir nesne olabilir) ve bizim örneğimizin bir örneğiTamamlama İşleyicisi.

Nio ET5 specificationsNio ET5 vs competitors

tamamlanmışyöntemdekiTamamlama İşleyicisiOkuma işlemi başarılı olduğunda çağrılır. Okunan bayt sayısını yazdırır, arabelleği çevirir ve ardından arabelleğin içeriğini bir dize olarak yazdırır.arızalıOkuma işlemi sırasında bir hata olması durumunda yöntem çağrılır ve bir hata mesajı yazdırır.

Okuma işlemi devam ederken programımız diğer görevleri yapmaya devam edebilir. Bu basit örnekte, sadece bir mesaj yazdırıyoruz ve ardından birkaç saniye uyuyoruz.

Şimdi ağ I/O için CompletionHandler kullanımından bahsedelim. Bir istemci - sunucu uygulaması oluşturduğunuzu ve gelen bağlantıları eşzamansız olarak yönetmek istediğinizi varsayalım.

Java.io.IOException'ı içe aktarın; Java.net.InetSocketAddress'i içe aktarın; java.nio.ByteBuffer'ı içe aktarın; java.nio.channels.AsynchronousServerSocketChannel'ı içe aktarın; java.nio.channels.AsynchronousSocketChannel'ı içe aktarın; Java.nio.channels.CompletionHandler'ı içe aktarın; public class AsyncServerExample { public static void main(String[] args) { try (AsynchronousServerSocketChannel serverSocketChannel = AsynchronousServerSocketChannel.open()) { serverSocketChannel.bind(new InetSocketAddress(8080)); System.out.println("Sunucu 8080 numaralı bağlantı noktasından başlatıldı"); serverSocketChannel.accept(null, new CompletionHandler<AsynchronousSocketChannel, Void>() { @Override public void Completed(AsynchronousSocketChannel clientChannel, Voidattachment) {serverSocketChannel.accept(null, this); System.out.println("Yeni istemci bağlandı"); ByteBuffer buffer = ByteBuffer.allocate(1024); clientChannel.read(buffer, buffer, new CompletionHandler<Integer, ByteBuffer>() { @Override public voidcomplete (Tamsayı sonucu, ByteBuffer eklentisi) { if (result > 0) {attachment.flip(); byte[] data = new byte[attachment.limit()];attach.get(data); String message = new String(data); System.out.println("Alınan: " + message); try { clientChannel.write(ByteBuffer.wrap(("Gönderdiğiniz: " + message).getBytes()).get(); } catch (Exception e) { e.printStackTrace(); } try { clientChannel.close(); } catch (IOException e) { e.printStackTrace() } } @Override public void başarısız oldu (Throwable exc, ByteBuffer eklentisi) { System.err.println("Okuma başarısız oldu: " + exc.getMessage()); try { clientChannel.close(); } catch (IOException e) { e.printStackTrace(); } } }); @Override public void başarısız oldu(Atılabilir exc, Void eklentisi) { System.err.println("Kabul başarısız oldu: " + exc.getMessage() } ); // Sunucunun çalışır durumda kalmasını sağlayın Thread.sleep(Long.MAX_VALUE); } catch (İstisna e) { e.printStackTrace(); } } }

Bu sunucu örneğinde, birAsenkronSunucuSocketChannelve 8080 numaralı bağlantı noktasına bağlayın.kabul etmeksunucu soket kanalındaki yöntem, birTamamlama İşleyicisi. Yeni bir istemci bağlandığında,tamamlanmışyöntemiTamamlama İşleyicisidenir. Bu yöntemin içinde, başka bir bağlantıyı kabul ederiz (böylece sunucu birden fazla istemciyi işleyebilir), yeni bir istemcinin bağlandığını belirten bir mesaj yazdırır ve ardından istemciden veri okumaya başlarız.

Başka bir tane kullanıyoruzTamamlama İşleyicisiOkuma işlemi için. Okuma başarılı olursa, alınan mesajı yazdırır ve müşteriye bir yanıt göndeririz. Eğer bir hata varsa hata mesajı yazdırıp client kanalını kapatıyoruz.

CompletionHandler'ı Java NIO eşzamansız G/Ç'de kullanmanın harika yanlarından biri, programınızı engellemeden birden fazla G/Ç işlemini aynı anda gerçekleştirmenize olanak sağlamasıdır. Bu, özellikle çok sayıda istemcinizin olduğu veya yüksek hacimli veri aktarımlarının olduğu senaryolarda, çok daha verimli ve duyarlı uygulamalara yol açabilir.

Elektrikli arabalarla ilgileniyorsanız, ilginizi çekebilirNio ET5 Elektrikli Araba. Tıpkı CompletionHandler'ın Java NIO asenkron I/O'da verimlilik ve esnekliği birleştirmesi gibi, stil ve teknolojiyi birleştiren şık ve yüksek performanslı bir elektrikli araçtır.

Bir NIO tedarikçisi olarak yüksek performanslı ve güvenilir sistemlerin önemini biliyorum. İster otomotiv endüstrisinde ister yazılım programlamada olsun, her zaman optimizasyon ve iyileştirmenin yollarını arıyoruz. Java NIO eşzamansız I/O hakkında daha fazla bilgi edinmek istiyorsanız veya ürünlerimiz ve hizmetlerimizle ilgili herhangi bir ihtiyacınız varsa bizimle iletişime geçmekten çekinmeyin. Projelerinizi bir sonraki aşamaya taşımanıza yardımcı olmak için buradayız. İhtiyaçlarınızı karşılamak için birlikte nasıl çalışabileceğimizi konuşalım.

Referanslar:

  • Java NIO Belgeleri
  • Çeşitli çevrimiçi programlama eğitimleri ve bloglar
Soruşturma göndermek