Szia! NIO beszállítóként mélyen belemerültem a Java NIO aszinkron I/O világába, és ma örömmel megosztom veletek, hogyan kell használni a CompletionHandlert a Java NIO aszinkron I/O-ban. Ez egy nagyon klassz koncepció, amely valóban feldobhatja a programozási játékot, különösen, ha nagy teljesítményű I/O műveletekkel foglalkozik.
Először is nézzük meg, miről is szól a Java NIO aszinkron I/O. A hagyományos Java I/O-ban a műveletek blokkolva vannak. Ez azt jelenti, hogy amikor egy I/O-műveletet végez, például fájlból olvas vagy adatokat kap egy hálózati socketből, a programnak meg kell várnia, amíg a művelet befejeződik, mielőtt a következő feladatra léphet. Ez igazi húzós lehet, különösen egy nagy forgalmú alkalmazásban, ahol nem szeretné, hogy a program várakozzon.
A Java NIO aszinkron I/O viszont lehetővé teszi, hogy a program más feladatokat is végezzen, miközben az I/O művelet folyamatban van. Visszahívás-alapú vagy jövő-alapú megközelítést használ, hogy értesítse a programot, amikor a művelet befejeződött. És itt jön be a CompletionHandler.
A CompletionHandler egy interfész a Java NIO-ban, amely két módszert határoz meg:elkészültéssikertelen. Aelkészültmetódus hívódik meg, amikor az aszinkron I/O művelet sikeresen befejeződik, és hozzáférést biztosít a művelet eredményéhez. Asikertelenmetódus hívódik meg, ha valami elromlik a művelet során, és információt ad a hibáról.
Kezdjük egy egyszerű példával a CompletionHandler használatára az aszinkron fájlolvasáshoz.
import java.nio.ByteBuffer; import java.nio.channels.AsynchronousFileChannel; import java.nio.channels.CompletionHandler; import java.nio.file.Path; import java.nio.file.Paths; import java.nio.file.StandardOpenOption; public class AsyncFileReadExample { public static void main(String[] args) { Path path = Paths.get("teszt.txt"); try (AsynchronousFileChannel fileChannel = AsynchronousFileChannel.open(útvonal, StandardOpenOption.READ)) { ByteBuffer puffer = ByteBuffer.allocate(1024); fileChannel.read(puffer, 0, puffer, new CompletionHandler<Integer, ByteBuffer>() { @A public void felülírása befejeződött(Integer eredmény, ByteBuffer melléklet) { System.out.println("Olvasás " + eredmény + " bytes"); buffer.flip(); bájt(getbuffer]datalim = új. byitte[getbuffer];talim); System.out.println(new String(data)); // Egyéb feladatok végrehajtása az olvasási művelet közben System.out.println("Egyéb feladatok végrehajtása..."); Thread.sleep(2000); } catch (e kivétel) { e.printStackTrace(); } } }
Ebben a példában először megnyitunk egyAsynchronousFileChannelolvasáshoz. Ezután kiosztunk aByteBufferhogy megtartsuk az olvasni kívánt adatokat. Hívjuk aolvasmetódus a fájlcsatornán, a puffer átadása, az olvasás megkezdésének pozíciója (ebben az esetben 0), egy melléklet (amely bármilyen objektum lehet, amelyet a művelettel együtt át kíván adni), ésCompletionHandler.


Aelkészültmódszer aCompletionHandlerakkor hívják meg, ha az olvasási művelet sikeres. Kiírja az olvasott bájtok számát, átfordítja a puffert, majd karakterláncként kiírja a puffer tartalmát. Asikertelenmetódus hívódik meg, ha hiba történik az olvasási művelet során, és hibaüzenetet nyomtat.
Amíg az olvasási művelet zajlik, programunk folytathatja az egyéb feladatok elvégzését. Ebben az egyszerű példában csak kinyomtatunk egy üzenetet, majd néhány másodpercig alszunk.
Most beszéljünk a CompletionHandler használatáról hálózati I/O-hoz. Tegyük fel, hogy kliens-kiszolgáló alkalmazást készít, és a bejövő kapcsolatokat aszinkron módon szeretné kezelni.
import java.io.IOException; import java.net.InetSocketAddress; import java.nio.ByteBuffer; import java.nio.channels.AsynchronousServerSocketChannel; import java.nio.channels.AsynchronousSocketChannel; import java.nio.channels.CompletionHandler; public class AsyncServerExample { public static void main(String[] args) { try (AsynchronousServerSocketChannel serverSocketChannel = AsynchronousServerSocketChannel.open()) { serverSocketChannel.bind(new InetSocketAddress)(8080)); System.out.println("A szerver a 8080-as porton indult"); serverSocketChannel.accept(null, new CompletionHandler<AsynchronousSocketChannel, Void>() { @Override public void kész(AsynchronousSocketChannel clientChannel, Void attachment) { serverSocketChannel.accept(null, this); By: System.out.printu buffer = System.out.printl"); ByteBuffer.allocate(1024); clientChannel.read(puffer, puffer, new CompletionHandler<Integer, ByteBuffer>() { @Override public void complete(Integer result, ByteBuffer attachment) { if (eredmény > 0) { attachment.flip(); byte[ittach) új bájt[itta attachment.get(data); String(data)("Fogadott: " + üzenet) (IOException e) { e.printStackTrace( } } @Override public void failed(Throwable exc, ByteBuffer attachment) { System.err.println("Olvasás sikertelen: " + exc.getMessage() } try { clientChannel.close()} fogás (IOTra); } @A nyilvános void felülbírálása sikertelen(Kidobható exc, érvénytelen csatolmány) { System.err.println("Sikertelen elfogadás: " + exc.getMessage() }); // A szerver futásának tartása Thread.sleep(Long.MAX_VALUE); } catch (e kivétel) { e.printStackTrace(); } } }
Ebben a szerverpéldában megnyitunk egyAsynchronousServerSocketChannelés a 8080-as porthoz kötjük. Ezután hívjuk aelfogadnimetódus a szerver socket csatornán, áthaladva aCompletionHandler. Amikor egy új kliens csatlakozik, aelkészültmódszere aCompletionHandlerhívják. Ezen a metóduson belül elfogadunk egy másik kapcsolatot (így a szerver több klienst is tud kezelni), kinyomtatjuk az új kliens csatlakozását jelző üzenetet, majd elkezdjük az adatok beolvasását a kliensről.
Mást használunkCompletionHandleraz olvasási művelethez. Ha az olvasás sikeres, kinyomtatjuk a beérkezett üzenetet és visszaküldjük a választ a kliensnek. Ha hiba történik, hibaüzenetet nyomtatunk, és bezárjuk az ügyfélcsatornát.
A CompletionHandler Java NIO aszinkron I/O-ban való használatának egyik nagyszerű tulajdonsága, hogy lehetővé teszi több I/O művelet egyidejű kezelését a program blokkolása nélkül. Ez sokkal hatékonyabb és érzékenyebb alkalmazásokhoz vezethet, különösen olyan esetekben, amikor nagyszámú ügyfél vagy nagy mennyiségű adatátvitel van.
Ha érdeklődik az elektromos autók iránt, érdeklődhet aNio ET5 elektromos autó. Ez egy karcsú és nagy teljesítményű elektromos jármű, amely ötvözi a stílust és a technológiát, ahogy a CompletionHandler a hatékonyságot és a rugalmasságot a Java NIO aszinkron I/O-ban.
NIO beszállítóként tisztában vagyok a nagy teljesítményű és megbízható rendszerek fontosságával. Legyen szó az autóiparról vagy a szoftverprogramozásról, mindig keressük az optimalizálási és fejlesztési módokat. Ha többet szeretne megtudni a Java NIO aszinkron I/O-ról, vagy bármilyen igénye van termékeinkkel és szolgáltatásainkkal kapcsolatban, ne habozzon kapcsolatba lépni velünk. Azért vagyunk itt, hogy segítsünk projektjeit a következő szintre emelni. Beszélgessünk arról, hogyan dolgozhatunk együtt az Ön igényeinek kielégítése érdekében.
Referenciák:
- Java NIO dokumentáció
- Különféle online programozási oktatóanyagok és blogok



























































