Middle
Kā organizēt datu apmaiņu starp diviem pavedieniem Java?
sobes.tech AI
Atbilde no AI
Datu apmaiņa starp straumēm Java var tikt organizēta šādi:
- Kopīgas mainīgās ar sinhronizāciju: Strauji izmanto kopīgas mainīgās, kuru piekļuve tiek sinhronizēta ar
synchronizedatslēgas vārdu, bloķēšanas (Locknojava.util.concurrent.locks) vai atomu mainīgajiem (Atomicnojava.util.concurrent.atomic). - Datu konvejeri (Piped Streams): Saistītie ievades/izvades straumes (
PipedInputStreamunPipedOutputStream) ļauj vienam straumēm rakstīt datus, bet otrai - tos lasīt:// Piped Streams izmantošana mēģiniet { PipedOutputStream pout = jauns PipedOutputStream(); PipedInputStream pin = jauns PipedInputStream(pout); // Strāva 1: rakstīšana jauns Tēma (()-> { mēģiniet { pout.write("Sveiki no straumes 1".getBytes()); pout.close(); } catch (Exception e) { e.printStackTrace(); } }).start(); // Strāva 2: lasīšana jauns Tēma (()-> { mēģiniet { int dati; kamēr ((dati = pin.read()) != -1) { System.out.print((char) dati); } pin.close(); } catch (Exception e) { e.printStackTrace(); } }).start(); } catch (Exception e) { e.printStackTrace(); } - Rindas (Queues): Izmantojot drošas straumes kolekcijas, piemēram,
BlockingQueue(piemēram,ArrayBlockingQueue,LinkedBlockingQueue), ļauj vienam straumēm pievienot elementus rindā, bet otram - tos izņemt:import java.util.concurrent.BlockingQueue; import java.util.concurrent.LinkedBlockingQueue; // Izmantojot BlockingQueue BlockingQueue<String> rinda = jauna LinkedBlockingQueue<>(); // Ražotājs jauns Tēma (()-> { mēģiniet { rinda.put("Ziņa 1"); rinda.put("Ziņa 2"); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } }).start(); // Patērētājs jauns Tēma (()-> { mēģiniet { System.out.println(rinda.take()); System.out.println(rinda.take()); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } }).start(); wait(),notify(),notifyAll(): Izmanto objektu monitoriem balstītu saskaņošanu starp straumēm. Viena straume izsaucwait(), lai gaidītu nosacījumu, otra -notify()vainotifyAll(), lai paziņotu gaidošajām straumēm par nosacījuma izmaiņām:// wait/notify izmantošana klase `Data` { privāts String message; privāts boolean empty = patiesība; publiska sinhronizēta String lasīt() { kamēr (empty) { mēģiniet { wait(); // gaidām datus } catch (InterruptedException e) { Thread.currentThread().interrupt(); } } empty = patiesība; notifyAll(); // paziņojam par rakstīšanas iespēju atgriezt message; } publiska sinhronizēta void rakstīt(String message) { kamēr (!empty) { mēģiniet { wait(); // gaidām, kamēr iepriekšējie dati tiks izlasīti } catch (InterruptedException e) { Thread.currentThread().interrupt(); } } empty = patiesība; this.message = message; notifyAll(); // paziņojam par jauniem datiem } }CompletableFuture: ļauj izveidot asenhroniskas aprēķinus un apvienot to rezultātus, nodrošinot datu apmaiņu caur atgrieztajām vērtībām un pabeigšanas apstrādātājiem.Exchanger: ļauj diviem straumēm apmainīties ar objektiem sinhronizācijas punktā.
Konkrēta metodes izvēle ir atkarīga no uzdevuma specifikas, nepieciešamā sinhronizācijas līmeņa, veiktspējas un realizācijas sarežģītības.