Middle
Hogyan szervezhető az adatok cseréje két szál között Java-ban?
sobes.tech MI
Válasz az MI-től
Az adatok cseréje a Java szálak között a következő módokon szervezhető:
- Közös változók szinkronizálással: A szálak közös változókat használnak, amelyekhez hozzáférést
synchronizedkulcsszóval, zárolásokkal (Lockajava.util.concurrent.locks-ből) vagy atomikus változókkal (Atomicajava.util.concurrent.atomic-ból) lehet szinkronizálni. - Adatcsövek (Piped Streams): Összekapcsolt bemeneti/kimeneti csövek (
PipedInputStreamésPipedOutputStream) lehetővé teszik, hogy az egyik szál adatokat írjon, a másik pedig olvassa azokat.// Piped Streams használata try { PipedOutputStream pout = new PipedOutputStream(); PipedInputStream pin = new PipedInputStream(pout); // 1. szál: írás new Thread(() -> { try { pout.write("Helló az 1. szálból".getBytes()); pout.close(); } catch (Exception e) { e.printStackTrace(); } }).start(); // 2. szál: olvasás new Thread(() -> { try { int data; while ((data = pin.read()) != -1) { System.out.print((char) data); } pin.close(); } catch (Exception e) { e.printStackTrace(); } }).start(); } catch (Exception e) { e.printStackTrace(); } - Sorok (Queues): A szálbiztos kollekciók, például a
BlockingQueue(pl.ArrayBlockingQueue,LinkedBlockingQueue) használata lehetővé teszi, hogy az egyik szál elemeket tegyen a sorba, a másik pedig kivonja azokat.import java.util.concurrent.BlockingQueue; import java.util.concurrent.LinkedBlockingQueue; // BlockingQueue használata BlockingQueue<String> queue = new LinkedBlockingQueue<>(); // Gyártó new Thread(() -> { try { queue.put("Üzenet 1"); queue.put("Üzenet 2"); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } }).start(); // Fogyasztó new Thread(() -> { try { System.out.println(queue.take()); System.out.println(queue.take()); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } }).start(); wait(),notify(),notifyAll()mechanizmusok: Objektum monitorjain alapuló szinkronizálásra használják. Egy szálwait()-et hív, hogy várjon egy feltételre, egy másik pedignotify()vagynotifyAll()-t, hogy értesítse a várakozó szálakat a feltétel változásáról.// wait/notify használata class Data { private String message; private boolean empty = true; public synchronized String read() { while (empty) { try { wait(); // Várakozás adatokra } catch (InterruptedException e) { Thread.currentThread().interrupt(); } } empty = true; notifyAll(); // Értesítés az írás lehetőségéről return message; } public synchronized void write(String message) { while (!empty) { try { wait(); // Várakozás, amíg az előző adatokat olvassák } catch (InterruptedException e) { Thread.currentThread().interrupt(); } } empty = false; this.message = message; notifyAll(); // Értesítés az új adatokról } }CompletableFuture: Lehetővé teszi aszinkron számítások létrehozását és eredményeik összekapcsolását, adatcserét biztosítva a visszatérő értékek és a befejezési kezelők révén.Exchanger: Két szál közötti objektumcsere szinkronizációs ponton.
A konkrét módszer kiválasztása a feladat sajátosságaitól, a szükséges szinkronizáció szintjétől, a teljesítménytől és a megvalósítás összetettségétől függ.