Javassa käytämme semaforia säikeiden synkronointiin. Sitä käytetään hallitsemaan pääsyä jaettuun resurssiin, joka käyttää laskurimuuttujaa. Java tarjoaa myös Semaphore-luokan, joka sisältää konstruktoreita ja erilaisia metodeja jaetun resurssin käytön hallintaan. Keskustelemme siitä myöhemmin tässä jaksossa.

Ennen kuin siirrymme eteenpäin tässä jaksossa, ymmärrämme ensin, mikä on semafori, semaforityypit, miten se toimii ja miten semafori toteutetaan. Kun tiedämme kaiken, siirrymme Java-semaforiohjelmiin.

Mikä on semafori?

Semaforia käytetään rajoittamaan niiden säikeiden määrää, jotka haluavat käyttää jaettua resurssia. Toisin sanoen se on ei-negatiivinen muuttuja, joka on jaettu säikeiden kesken ja jota kutsutaan laskuriksi. Se asettaa säikeille rajan. Mekanismi, jossa säie odottaa semaforia, voi olla merkkinä muille säikeille.

  • Jos laskuri > 0, jaettuihin resursseihin annetaan pääsy.
  • Jos laskuri = 0, pääsy jaettuihin resursseihin evätään.

Lyhyesti sanottuna laskuri pitää kirjaa siitä, kuinka monta käyttöoikeutta se on antanut jaettuun resurssiin. Semafori siis antaa säikeille luvan resurssin jakamiseen.

Semaforin ominaisuudet

Semaforilla on seuraavat ominaisuudet:

  • Semafori tarjoaa synkronointia säikeiden välillä.
  • Semafori vähentää synkronoinnin tasoa. Tarjoaa siis matalan tason synkronointimekanismin.
  • Semafori ei sisällä negatiivista arvoa. Se pitää hallussaan arvoa, joka voi olla joko suurempi kuin nolla tai yhtä suuri kuin nolla.
  • Voidaan toteuttaa semafori käyttäen testioperaatiota ja keskeytyksiä, ja käytetään tiedoston kuvaajia sen suorittamiseen.

Semaforin toiminta

Semafori valvoo jaettua resurssia laskurimuuttujan avulla. Laskuri on ei-negatiivinen arvo. Se sisältää arvon, joka on joko suurempi kuin 0 tai yhtä suuri kuin 0.

  • Jos laskuri > 0, säie saa luvan käyttää jaettua resurssia ja laskurin arvo pienenee 1:llä.
  • Muussa tapauksessa säie estyy, kunnes lupa saadaan.
  • Kun säikeen suoritus on päättynyt, niin silloin resurssia ei enää tarvita ja säie vapauttaa sen. Resurssin vapauttamisen jälkeen laskurin arvo kasvaa 1:llä.
  • Jos toinen säie odottaa resurssin hankkimista, säie hankkii luvan tuolloin.
  • Jos laskuri = 0, säie ei saa lupaa käyttää jaettua resurssia.

Ymmärretäänpä semaforin toimintaa vuokaavion avulla.

Java-semafori

Semaforien tyypit

Semaforeja on neljää tyyppiä, jotka ovat seuraavat:

  • Laskusemaforit
  • Rajoitetutemaforit
  • Ajoitetutemaforit
  • Binäärisetemaforit

Java-semafori

Keskustellaan yksi kerrallaan yksityiskohtaisesti.

Laskentasemaforit

Laskentasemaforeja käytetään ratkaisemaan tilanne, jossa useampi kuin yksi prosessi haluaa suorittaa kriittisessä osassa samanaikaisesti. Tämän ongelman ratkaisemiseksi käytetään siis laskentasemaforia. Tarkastellaan esimerkiksi seuraavaa koodinpätkää.

Katsotaanpa laskentasemaforien toteutusta.

CountingSemaphoresExample.java

Bounded Semaphores

Bounded Semaphoresin avulla voimme asettaa ylärajan. Sitä käytetään laskentasemafoorien sijasta, koska laskentasemafoorit eivät sisällä mitään yläraja-arvoa. Yläraja-arvo ilmaisee, kuinka monta signaalia se voi tallentaa. Tarkastellaan esimerkiksi seuraavaa koodinpätkää.

Katsotaanpa rajattujen semaforien toteutusta.

BoundedSemaphoresExample.java

Timed Semaphores

Timed Semaphores mahdollistaa säikeen suorittamisen määritellyn ajanjakson ajan. Tietyn ajan kuluttua ajastin nollautuu ja vapauttaa kaikki muut luvat.

Katsotaanpa ajastettujen semafoorien toteutus.

TimedSemaphoresExample.java

Binääriset semafoorit

Binääriset semafoorit ovat samanlaisia kuin laskevat semafoorit. Mutta muista, että se hyväksyy vain binääriarvoja joko 0 tai 1. Sen toteutus on helppo verrattuna muihin semaforeihin. Jos arvo on 1, signaalioperaatio onnistuu, muuten epäonnistuu.

Katsotaan binäärisemaforien toteutus.

BinarySemaphoresExample.java

Semafori Javassa

Javassa se on säikeiden synkronointikonstruktio. Konstruktiossa käytetään laskuriksi kutsuttua muuttujaa, joka ohjaa pääsyä jaettuun resurssiin. Se on muuttujatyyppi, jota käytetään rinnakkaisten prosessien hallintaan ja myös niiden synkronointiin. Sitä käytetään myös kilpajuoksutilanteiden välttämiseen. Se rajoittaa säikeiden määrää, jotka voivat käyttää jaettua resurssia.

Voidaan esimerkiksi rajoittaa tiedoston käyttö enintään 10 yhteydelle samanaikaisesti.

Java Semaphore-luokka

Java tarjoaa Semaphore-luokan toteuttamaan semaforimekanismin. Se kuuluu java.util.concurrent-pakettiin. Se toteuttaa Serializable-rajapinnan. Näin ollen manuaalista toteutusta ei tarvita.

Semaphore-luokka tarjoaa seuraavat kaksi konstruktoria:

  • Semaphore(int permits)
  • Semaphore(int permits, boolean fair)

Semaphore(int permits)

Semaphore-luokka luo Semaphoren ja jäsennettii argumenttina lupien lukumäärän (alun perin käytettävissä olevien lupien määrä). Se määrittää niiden säikeiden määrän, jotka voivat jakaa resurssin kerrallaan. Lupien arvo voi olla negatiivinen. Tällöin on tapahduttava vapautus ennen kuin mitään hankintoja myönnetään.

Syntaksi:

Semaphore(int permits, boolean fair)

Luo Semaphorin annetulla lupien lukumäärällä ja annetuilla fairness-asetuksilla.

Syntaksi:

Parsii kaksi parametria:

  • permits: Lupien arvo voi olla negatiivinen. Tällöin vapautuksen on tapahduttava ennen kuin acquires myönnetään.
  • fair: Jos asetamme arvon true, semafori takaa FIFO:n säikeille siinä järjestyksessä kuin niitä pyydetään, false Oletusarvoisesti kaikki resurssia odottavat säikeet myöntävät permit:in määrittelemättömässä järjestyksessä.

Semafori-luokan metodit

Luokka tarjoaa seuraavat metodit:

acquire()-metodi: Metodi hankkii luvat semaforista ja estää, kunnes sellainen on käytettävissä tai säie keskeytyy. Se vähentää käytettävissä olevien lupien lukumäärää 1:llä.

Jos nykyiselle säikeelle ei ole saatavilla lupaa, säie muuttuu käytöstä poistetuksi säikeaikataulutusta varten. Nykyinen säie siirtyy inaktiiviseen tilaan, kunnes tapahtuu jompikumpi kahdesta asiasta:

  • Jos toinen säie kutsuu release()-metodia vapauttaakseen resurssin, niin nykyinen säie saa luvat.
  • Jos toinen säie keskeyttää nykyisen säikeen.

Hyökkäys heittää InterruptedExceptionin, jos nykyinen säie on keskeytetty. Metodi ei palauta mitään arvoa.

Syntaksi:

release() Metodi: Se vapauttaa luvan ja palauttaa sen semaforiin. Se kasvattaa käytettävissä olevien lupien määrää 1:llä. Jos säie yrittää hankkia lupaa, semafori antaa luvan hankkia resurssin, jonka muut säikeet juuri vapauttivat. Lisäksi kyseinen säie otetaan huomioon säikeaikataulutuksessa.

Syntaksi:

availablePermits() Metodi: Metodi palauttaa resurssin myöntämistä varten semafoorissa käytettävissä olevien lupien määrän. Yleensä sitä käytetään debuggaus- ja testaustarkoituksiin.

Syntax:

Ymmärretään edellä mainittuja metodeja yksinkertaisen esimerkin avulla.

Semaforin käyttäminen lukituksena

Java antaa meille mahdollisuuden käyttää semaforia lukituksena. Se tarkoittaa, että se lukitsee pääsyn resurssiin. Jokaisen säikeen, joka haluaa käyttää lukittua resurssia, on kutsuttava acquire()-metodia ennen resurssin käyttämistä lukituksen hankkimiseksi. Säikeen on vapautettava lukko kutsumalla release()-metodia tehtävän suorittamisen jälkeen. Muista, että aseta ylärajaksi 1. Tarkastellaan esimerkiksi seuraavaa koodinpätkää:

Katsotaan esimerkki semaforista ja käytetään semaforia lukituksena.

SemaphoreAsLock.java

Output:

Java Semaphore

Huomautus: Kun suoritamme yllä olevan ohjelman, saamme joka kerta erilaisen tulosteen. Joten sinun tulostuksesi voi poiketa yllä esitetystä tulosteesta.

Java Semaphore Esimerkki

Ymmärretäänpä semafoorimekanismia Java-ohjelman avulla. Seuraavassa esimerkissä olemme luoneet Semaphore-luokan konstruktorin, jonka aloituslupa-arvo on 3.

SemaphoreExample.java

Output:

Java Semaphore

Vastaa

Sähköpostiosoitettasi ei julkaista.