JavaRush /Java Blog /Random-TL /Halimbawa ng SynchronousQueue sa Java - paglutas ng probl...
profeg
Antas

Halimbawa ng SynchronousQueue sa Java - paglutas ng problemang Producer Consumer

Nai-publish sa grupo
Halimbawa ng SynchronousQueue sa Java - paglutas ng problemang Producer Consumer
Ang SynchronousQueue ay isang espesyal na uri ng BlockingQueue kung saan ang bawat insert na operasyon ay dapat maghintay para sa isang kaukulang utos ng pag-alis sa isa pang thread, at vice versa. Kapag tinawag mo ang put() na pamamaraan sa isang SynchronousQueue, haharang ito hanggang sa kunin ng isa pang thread ang elementong iyon mula dito. Alinsunod dito, kung ang isa pang thread ay sumusubok na mag-alis ng isang elemento mula dito, at ang elemento ay wala doon, pagkatapos ay ang thread na iyon ay humaharang hanggang sa ilagay ng kabilang thread ang elemento sa pila. Maaari mong isipin ang SynchronousQueue bilang isang atleta ( thread ) na tumatakbo gamit ang Olympic torch, tumatakbo siya gamit ang torch (ang bagay na ipinapasa) at ipinapasa ito sa isa pang atleta na naghihintay sa kabilang panig. Kung bibigyan mo ng pansin ang pangalan, mauunawaan mo na ang SynchronousQueue ay pinangalanan para sa isang dahilan, naglilipat ito ng data nang sabay-sabay sa isa pang thread ; naghihintay ito para sa isang tao na kunin ang data sa halip na ilagay lamang ito at lumabas (isang asynchronous na operasyon). Kung pamilyar ka sa CSP at Ada, alam mo na ang mga naka-synchronize na pila ay katulad ng pagpupulong ng mga thread. Ang mga ito ay angkop para sa mga control transfer construct kung saan ang isang bagay na tumatakbo sa isang thread ay dapat mag-synchronize sa isang bagay sa isa pang thread upang maipasa ang ilang impormasyon, kaganapan, o gawain dito. Sa mga nakaraang multi-threaded programming tutorial, natutunan namin kung paano lutasin ang problema ng producer-consumer gamit ang wait and notify at BlockingQueue na mga paraan . Ngayon ay matututunan natin kung paano ilapat ang pattern ng producer-consumer gamit ang SynchronousQueue. Sinusuportahan din ng klase na ito ang patas na pag-uugali para sa pag-order ng mga paghihintay ng mga thread ng producer at consumer. Bilang default, ang pag-order na ito ay hindi ginagarantiyahan. Gayunpaman, ang mga queue na ginawa gamit ang mga patas na property ay ginagarantiyahan ang access para sa mga thread sa isang FIFO (Firs In First Out) queue.
Producer/Consumer gamit ang SynchronousQueue sa Java.
Halimbawa ng SynchronousQueue sa Java - paglutas ng problemang Producer Consumer - 1 Tulad ng sinabi ko sa itaas, walang mas mahusay kaysa sa problema ng producer-consumer para sa pag-unawa sa inter-thread na komunikasyon sa anumang programming language. Sa problemang ito, ang isang thread ay gumaganap bilang isang producer na gumagawa ng mga kaganapan at mga gawain, at ang isa pang thread ay kumikilos bilang isang mamimili nito. Ang isang shared buffer ay ginagamit upang ilipat ang data mula sa producer patungo sa consumer. Ang kahirapan sa paglutas ng problemang ito ay dumarating sa matinding mga kaso, halimbawa, kapag ang tagagawa ay napilitang maghintay dahil... puno ang buffer o napilitang maghintay ang mamimili dahil walang laman ang buffer. Madali itong nalutas, dahil... Ang blocking queue ay hindi lamang nagbigay ng buffer para sa pag-iimbak ng data, kundi pati na rin sa flow control, pagharang sa thread na tinatawag ang put() method (Producer) kung puno ang buffer, at pagharang sa thread na tinatawag ang take() method (Consumer) kung ang walang laman ang buffer. Ngayon ay malulutas natin ang parehong problema gamit ang SynchronousQueue, isang espesyal na uri ng parallel na mga koleksyon na may zero na kapasidad. Sa sumusunod na halimbawa, mayroon kaming dalawang thread na tinatawag na PRODUCER at CONSUMER (laging bigyan ng mga pangalan ang mga thread, ito ay isang napakagandang istilo ng multi-threaded programming). Ang unang thread ay nagpo-post ng puntos sa laro, at ang pangalawang thread ay kumonsumo nito. Ang iskor sa laro ay hindi hihigit sa isang bagay na may uri ng String. Ngunit kung patakbuhin mo ang programa na may ibang uri, hindi mo mapapansin ang anumang pagkakaiba. Upang maunawaan kung paano gumagana ang SynchronousQueue, at kung paano lutasin ang problema ng producer-consumer, kailangan mong: patakbuhin ang program para sa pag-debug (debug) sa Eclipse environment , o simulan lang ang thread ng producer sa pamamagitan ng pagkomento sa consumer.start(); kung ang consumer thread ay hindi tumatakbo pagkatapos ay ang producer thread ay haharangan sa queue.put(event); kung tumatakbo, hindi mo makikita ang producer na [PRODUCER] na nag-publish ng :FOUR na kaganapan. Nangyayari ito dahil tiyak na pag-uugali ng SynchronousQueue, na nagsisiguro na ang thread na nagpo-post ng data ay haharang hanggang sa makuha ng isa pang thread ang data, at kabaliktaran. Maaari mong subukan ang natitirang bahagi ng code sa pamamagitan ng pagkomento sa producer.start(); at nagsisimula lamang sa consumer thread. Kung maingat mong pag-aralan kung ano ang output ng programa, mapapansin mo na ang pagkakasunud-sunod ng output ay baligtad. Mukhang kinuha ng [CONSUMER] thread ang data bago ito ginawa ng [PRODUCER] thread. Ito ay dahil hindi ginagarantiya ng SynchronousQueue ang pagpila bilang default. Ngunit mayroon itong mga panuntunan sa pagiging patas na nagtatakda ng access sa mga thread sa FIFO order. Maaari mong paganahin ang mga panuntunang ito sa pamamagitan ng pagpasa ng true sa overloaded na SynchronousQueue constructor tulad nito: import java.util.concurrent.SynchronousQueue; /** * Java Program to solve Producer Consumer problem using SynchronousQueue. A * call to put() will block until there is a corresponding thread to take() that * element. * * @author Javin Paul */ public class SynchronousQueueDemo{ public static void main(String args[]) { final SynchronousQueue queue = new SynchronousQueue (); Thread producer = new Thread("PRODUCER") { public void run() { String event = "FOUR"; try { queue.put(event); // thread will block here System.out.printf("[%s] published event : %s %n", Thread .currentThread() .getName(), event); } catch (InterruptedException e) { e.printStackTrace(); } } }; producer.start(); // starting publisher thread Thread consumer = new Thread("CONSUMER") { public void run() { try { String event = queue.take(); // thread will block here System.out.printf("[%s] consumed event : %s %n", Thread .currentThread() .getName(), event); } catch (InterruptedException e) { e.printStackTrace(); } } }; consumer.start(); // starting consumer thread } } Output: [CONSUMER] consumed event : FOUR [PRODUCER] published event : FOUR new SynchronousQueue(boolean fair).
Ano ang kailangan mong tandaan tungkol sa SynchronousQueue sa Java.

Narito ang ilang mahahalagang katangian ng espesyal na uri ng pagharang na pila sa Java. Ito ay lubhang kapaki-pakinabang upang ipasa ang data mula sa isang thread patungo sa isa pa sa isang naka-synchronize na paraan. Ang pila na ito ay walang kapasidad at na-block hanggang sa isa pang thread ay palayain ito.

  1. Bina-block ang SynchronousQueue, at hanggang sa ang isang thread ay handa nang kumuha ng data, susubukan ng isa pang maglagay ng data.
  2. Walang volume ang SynchronousQueue. Ibig sabihin, hindi ito naglalaman ng data.
  3. Ginagamit ang SynchronousQueue upang magpatupad ng diskarte sa pag-forward queuing, kung saan ipinapasa ng isang thread ang kontrol sa naghihintay na thread, o gagawa ng bago kung pinapayagan, kung hindi, hindi ililipat ang kontrol.
  4. Hindi pinapayagan ng queue na ito ang null data. Ang isang pagtatangka upang magdagdag ng isang null elemento ay magtapon ng isang NullPointerException .
  5. Kung gumagamit ka ng iba pang mga pamamaraan mula sa Collection (tulad ng mga naglalaman), kumikilos ang SynchronousQueue na parang walang laman na koleksyon.
  6. Hindi mo magagamit ang paraan ng pagsilip ng SynchronousQueue dahil umiiral lang ang elemento kapag sinubukan mong alisin ito; Gayundin, hindi ka makakapagpasok ng mga elemento (gamit ang anumang paraan) hanggang sa subukan ng isa pang thread na alisin ito.
  7. Hindi mo magagamit ang iterator para sa SynchronousQueue dahil... wala itong elemento.
  8. Maaaring gawin ang SynchronousQueue gamit ang mga patas na panuntunan, kung saan ang access sa mga thread ay ginagarantiyahan sa FIFO order.
Marahil ito ay tungkol sa SynchronousQueue sa Java. Tiningnan namin ang ilan sa mga espesyal na feature ng multi-threaded na koleksyon na ito, at natutunan namin kung paano lutasin ang klasikong problema ng producer-consumer gamit ang SynchronousQueue sa Java. Sa pamamagitan ng paraan, ang pagtawag dito ng isang Queue ay hindi ganap na tama, dahil... hindi ito naglalaman ng mga elemento. Ang tawag sa put() ay hindi makukumpleto hanggang sa isa pang thread na tawag ay tumagal(). Mas tama na isipin ito bilang isang lugar ng pagpupulong ng mga thread, kung saan nagbabahagi sila ng isang bagay. Sa madaling salita, ito ay isang utility para sa naka-synchronize na pagpasa ng mga bagay sa Java, marahil isang mas ligtas na alternatibo sa paraan ng paghihintay at pag-abiso .
Mga komento
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION