beställd Serverräknare
exemplet ovan är en beställd serverräknare som vi vill bygga. När du klickar på knappen:
- en asynkron begäran skickas till en server
- servern ökar en intern räknare
- servern returnerar det aktuella räknarvärdet
- klienten (vår webbsida) visar räknaren i en skål som visas ovan.
det är viktigt att ordningen på siffrorna bevaras när de tas emot. Så hur kan vi synkronisera ordningen på förfrågningarna? Vi vet att nätverksförfrågningar är asynkrona. Det är helt möjligt för den första begäran att ta längre tid att komma fram än den andra begäran, eller den andra begäran att ta längre tid än den tredje begäran, och så vidare. Denna out-of-order ankomst av förfrågningar kommer att vara ett problem för vår ansökan.
’ingen synkronisering’ – metoden
vad skulle hända om vi skulle utveckla denna applikation utan synkroniseringskonstruktioner? Här är ett exempelimplementering av en simulering av denna applikation utan synkronisering.
servern simuleras med processCommmand()
och nätverksfördröjningarna simuleras med serverDelay()
. Eftersom det inte finns några synkroniseringsmekanismer, när knappen ”Klicka på mig” klickas, avfyras en ny begäran omedelbart.
detta är resultatet av denna implementering.
uh oh — siffrorna, som förväntat, dyker upp i ordning, och vi har misslyckats med att göra vår ansökan för att visa siffror i ordning.
att övervinna problemet med out-of-order med Mutex
problemet är att nätverksförfrågningar är i ordning, men vår ansökan vill att de ska vara i ordning. Ett sätt att lösa detta är att använda ett Mutex-lås för att bara tillåta att en begäran behandlas åt gången och blockera de andra förfrågningarna tills det är deras tur.
här är implementeringen med Mutex.
mutex API-användningsflödet är följande:
- linje 23: en begäran om att förvärva
clientLock
initieras. Denna begäran kommer att blockera om någon annan redan har förvärvat låset och inte har släppt det ännu - linje 33: klientlåset släpps efter att servern har svarat och vi har visat skålen. Detta gör att andra knappklickhändelser nu kan tävla om låset och initiera sin begäran om servernätverk!
denna låsmekanism garanterar att endast en knapphändelse kommer att behandlas åt gången, blockera och köa de andra. Vi har nu uppnått den avsedda beställda implementeringen av vårt ursprungliga exempel som visades i början!
begränsa antalet synliga skålar
vad händer om du inte gillar att flera skålar kan översvämma skärmen åt gången? Vi kan utöka vår logik för att begränsa antalet skålar som visas åt gången. Vår synkroniseringskonstruktion här skulle vara en semafor!
Tänk på en Sempahore som en Mutex, men det kan tillåta flera asynkrona förfrågningar att utföra en bit kod åt gången. Du kan också konfigurera det maximala antalet!
med en Mutex och Semafor kunde jag begränsa antalet skålar på skärmen till 2 åt gången.
och här är koden associerad med exemplet ovan
linje 6
sempahore-strukturen initieras med värdet 2, vilket anger att endast högst 2 skålar kan visas en gång.
linje 26-31
vår semafor logik kommer att hjälpa oss när vi vill visa Toast. Vi försöker förvärva Sempahore. Om vi lyckades skapar vi Toast-objektet, och sedan skickar vi releaseSemaphore()
till toasts completeCallback
– funktion. Denna återuppringning kallas när skålen avvisas.