Middle
როგორ შეიძლება ორგანიზება გაუკეთდეს მონაცემთა გაცვლას ორ ნაკადს შორის Java-ში?
sobes.tech AI
პასუხი AI-სგან
Java- ში ნაკადებს შორის მონაცემთა გაცვლა ორგანიზებული შეიძლება შემდეგი მეთოდებით:
- საერთო ცვლადები სინქრონიზაციით: ნაკადები იყენებენ საერთო ცვლადებს, რომელთა წვდომა სინქრონიზირებულია
synchronizedსაკვანძო სიტყვით, ბლოკებით (Lockjava.util.concurrent.locks-დან) ან ატომური ცვლადებით (Atomicjava.util.concurrent.atomic-დან): - მონაცემთა კონვეიერები (Piped Streams): დაკავშირებული შესვლის/გამოსვლის ნაკადები (
PipedInputStreamდაPipedOutputStream) საშუალებას აძლევს ერთ ნაკადს წერდეს მონაცემებს, ხოლო მეორე - კითხულობს:// Piped Streams-ის გამოყენება სცადეთ { PipedOutputStream pout = ახალი PipedOutputStream(); PipedInputStream pin = ახალი PipedInputStream(pout); // ნაკადი 1: წერა ახალი თემა (()-> { სცადეთ { pout.write("გამარჯობა ნაკადიდან 1".getBytes()); pout.close(); } დაჭერა (Exception e) { e.printStackTrace(); } }).start(); // ნაკადი 2: კითხვა ახალი თემა (()-> { სცადეთ { int data; სანამ ((data = pin.read()) != -1) { System.out.print((char) data); } pin.close(); } დაჭერა (Exception e) { e.printStackTrace(); } }).start(); } დაჭერა (Exception e) { e.printStackTrace(); } - ნაკადები (Queues): გამოყენებით უსაფრთხო კოლექციებს, როგორიცაა
BlockingQueue(მაგალითად,ArrayBlockingQueue,LinkedBlockingQueue), ერთ ნაკადს შეუძლია ელემენტების დამატება რიგში, ხოლო მეორე - ამოღება:იმპორტი java.util.concurrent.BlockingQueue; იმპორტი java.util.concurrent.LinkedBlockingQueue; // გამოყენება BlockingQueue BlockingQueue<String> queue = ახალი LinkedBlockingQueue<>(); // მწარმოებელი ახალი თემა (()-> { სცადეთ { queue.put("შეტყობინება 1"); queue.put("შეტყობინება 2"); } დაჭერა (InterruptedException e) { Thread.currentThread().interrupt(); } }).start(); // მომხმარებელი ახალი თემა (()-> { სცადეთ { System.out.println(queue.take()); System.out.println(queue.take()); } დაჭერა (InterruptedException e) { Thread.currentThread().interrupt(); } }).start(); wait(),notify(),notifyAll(): გამოიყენება ობიექტის მონიტორების საფუძველზე ნაკადების სინქრონიზაციისთვის. ერთი ნაკადი იძახისwait(), რათა დაელოდოს პირობას, მეორე -notify()ანnotifyAll(), რათა აცნობოს მოლოდინში მყოფ ნაკადებს პირობების ცვლილების შესახებ:// wait/notify-ის გამოყენება კლასი `Data` { პირადი String message; პირადი boolean empty = ჭეშმარიტი; საჯარო სინქრონული String read() { სანამ (empty) { სცადეთ { wait(); // მონაცემების მოლოდინში } დაჭერა (InterruptedException e) { Thread.currentThread().interrupt(); } } empty = ჭეშმარიტი; notifyAll(); // შეტყობინება წერის შესაძლებლობის შესახებ დაბრუნება message; } საჯარო სინქრონული void write(String message) { სანამ (!empty) { სცადეთ { wait(); // მოლოდინში წინა მონაცემების წაკითხვა } დაჭერა (InterruptedException e) { Thread.currentThread().interrupt(); } } empty = ჭეშმარიტი; this.message = message; notifyAll(); // ახალი მონაცემების არსებობის შეტყობინება } }CompletableFuture: საშუალებას აძლევს შექმნას ასინქრონული გამოთვლები და მათი შედეგების გაერთიანება, უზრუნველყოფს მონაცემთა გაცვლას დაბრუნებული მნიშვნელობებისა და დამთავრების დამუშავებლების საშუალებით.Exchanger: საშუალებას აძლევს ორ ნაკადს გაცვალოს ობიექტები სინქრონიზაციის წერტილში.
შერჩევა კონკრეტული მეთოდის დამოკიდებულია ამოცანის სპეციფიკაზე, საჭირო სინქრონიზაციის დონეზე, შესრულების სიჩქარეზე და განხორციელების სირთულეზე.