CodeGym/Java kurs/Modul 3/Flertrådede mønstre

Flertrådede mønstre

Tilgjengelig

3.1 Aktivt objekt

Et aktivt objekt er et designmønster som skiller utførelsestråden til en metode fra tråden den ble kalt i. Hensikten med dette mønsteret er å tilveiebringe parallell utførelse ved bruk av asynkrone metodeanrop og en forespørselsbehandlingsplanlegger.

Forenklet versjon:

aktivt objekt

Klassisk variant:

Aktivt objekt 2

Denne malen har seks elementer:

  • Et proxy-objekt som gir et grensesnitt til klientens offentlige metoder.
  • Et grensesnitt som definerer tilgangsmetoder for det aktive objektet.
  • Liste over innkommende forespørsler fra kunder.
  • En planlegger som bestemmer rekkefølgen spørringene skal utføres i.
  • Implementering av aktive objektmetoder.
  • En tilbakeringingsprosedyre eller en variabel for at klienten skal motta et resultat.

3.2 lås

Låsemønsteret er en synkroniseringsmekanisme som gir eksklusiv tilgang til en delt ressurs mellom flere tråder. Låser er én måte å håndheve retningslinjer for samtidighetskontroll.

I utgangspunktet brukes en myk lås, med antagelsen om at hver tråd prøver å "skaffe seg låsen" før de får tilgang til den tilsvarende delte ressursen.

Noen systemer tilbyr imidlertid en obligatorisk låsemekanisme der et uautorisert tilgangsforsøk til en låst ressurs vil bli avbrutt ved å kaste et unntak på tråden som forsøkte å få tilgang.

En semafor er den enkleste typen lås. Når det gjelder datatilgang, skilles det ikke mellom tilgangsmoduser: delt (skrivebeskyttet) eller eksklusiv (lese-skrive). I delt modus kan flere tråder be om en lås for å få tilgang til data i skrivebeskyttet modus. Den eksklusive tilgangsmodusen brukes også i oppdaterings- og slettealgoritmene.

låsemønster

Låsetypene kjennetegnes av strategien for å blokkere fortsettelsen av utførelsen av tråden. I de fleste implementeringer forhindrer en forespørsel om en lås at tråden fortsetter å kjøre til den låste ressursen er tilgjengelig.

En spinlock er en lås som venter i en løkke til tilgang er gitt. En slik lås er svært effektiv hvis en tråd venter på en lås i en liten stund, og unngår dermed overdreven omlegging av tråder. Kostnaden for å vente på tilgang vil være betydelig hvis en av trådene holder låsen lenge.

låsemønster 2

For å effektivt implementere låsemekanismen kreves støtte på maskinvarenivå. Maskinvarestøtte kan implementeres som en eller flere atomoperasjoner som "test-og-sett", "hent-og-legg til" eller "sammenlign-og-bytt". Slike instruksjoner lar deg sjekke uten avbrudd at låsen er ledig, og i så fall anskaffe låsen.

3.3 Monitor

Monitormønsteret er en prosessinteraksjon og synkroniseringsmekanisme på høyt nivå som gir tilgang til delte ressurser. En tilnærming til å synkronisere to eller flere datamaskinoppgaver ved å bruke en felles ressurs, vanligvis maskinvare eller et sett med variabler.

I skjermbasert multitasking setter kompilatoren eller tolken transparent inn låse-opplåsningskode i passende formaterte rutiner, transparent for programmereren, og sparer programmereren fra å eksplisitt kalle synkroniseringsprimitiver.

Monitoren består av:

  • et sett med prosedyrer som samhandler med en delt ressurs
  • mutex
  • variabler knyttet til denne ressursen
  • en invariant som definerer forhold for å unngå en rasetilstand

Monitorprosedyren innhenter mutex før arbeidet starter og holder den enten til prosedyren avsluttes eller til en viss tilstand er ventet på. Hvis hver prosedyre garanterer at invarianten er sann før du slipper mutexen, kan ingen oppgave skaffe ressursen i en rasetilstand.

Slik fungerer den synkroniserte operatøren i Java med metodene wait()og notify().

3.4 Dobbeltsjekk låsing

Dobbeltsjekket låsing er et parallelt designmønster beregnet på å redusere kostnadene ved å skaffe en lås.

Først sjekkes blokkeringstilstanden uten noen synkronisering. En tråd forsøker å skaffe en lås bare hvis resultatet av kontrollen indikerer at den trenger å skaffe låsen.

//Double-Checked Locking
public final class Singleton {
private static Singleton instance; //Don't forget volatile modifier

public static Singleton getInstance() {
     if (instance == null) {                //Read

         synchronized (Singleton.class) {    //
             if (instance == null) {         //Read Write
                 instance = new Singleton(); //
             }
         }
     }
 }

Hvordan lage et singleton-objekt i et trådsikkert miljø?

public static Singleton getInstance() {
   if (instance == null)
    instance = new Singleton();
}

Hvis du lager et Singleton-objekt fra forskjellige tråder, kan det være en situasjon hvor flere objekter opprettes samtidig, og dette er uakseptabelt. Derfor er det rimelig å pakke inn objektopprettelsen i en synkronisert setning.

public static Singleton getInstance() {
    synchronized (Singleton.class) {
        if (instance == null)
        instance = new Singleton();
    }
}

Denne tilnærmingen vil fungere, men den har en liten ulempe. Etter at objektet er opprettet, hver gang du prøver å få det i fremtiden, vil det bli utført en sjekk i den synkroniserte blokken, noe som betyr at den nåværende tråden og alt knyttet til den vil bli låst. Så denne koden kan optimaliseres litt:

public static Singleton getInstance() {
     if (instance != null)
        return instance;

    synchronized (Singleton.class) {
        if (instance == null)
        instance = new Singleton();
    }
}

På noen språk og/eller på noen maskiner er det ikke mulig å implementere dette mønsteret på en sikker måte. Derfor kalles det noen ganger et antimønster. Slike funksjoner har ført til utseendet til "skjer før" strenge rekkefølgeforhold i Java Memory Model og C++ Memory Model.

Det brukes vanligvis til å redusere kostnadene ved å implementere lat initialisering i flertrådede programmer, for eksempel Singleton-designmønsteret. Ved lat initialisering av en variabel, blir initialisering utsatt til verdien av variabelen er nødvendig i beregningen.

3.5 Planlegger

Planleggeren er et parallelt designmønster som gir en mekanisme for å implementere en planleggingspolicy, men er uavhengig av en bestemt policy. Styrer rekkefølgen som tråder skal kjøre sekvensiell kode i, ved å bruke et objekt som eksplisitt spesifiserer sekvensen av ventende tråder.

1
Oppgave
Modul 3,  nivålekse
Låst
Trust, but Verify
task4123
Kommentarer
  • Populær
  • Ny
  • Gammel
Du må være pålogget for å legge igjen en kommentar
Denne siden har ingen kommentarer ennå