Clojure: funksjonell programmering og backendutvikling på JVM · leksjon

Refs, agenter og atomer for tilstand

Lær å bruke Clojures grunnleggende primitiver for samtidighet til å håndtere endringsbar tilstand trygt på tvers av tråder.

Leksjon 1 av 413 trinn

Refs, agenter og atomer for tilstand er en gratis leksjon i Clojure: funksjonell programmering og backendutvikling på JVM på CoddyKit. Dette er leksjon 1 av 4. Du kan lese hele leksjonen gratis nedenfor – og deretter øve praktisk i nettleseren med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt. Den er en del av læringsløpet i Clojure: funksjonell programmering og backendutvikling på JVM, og fremdriften din synkroniseres mellom nettet og CoddyKit-appen. Kurset i Clojure: funksjonell programmering og backendutvikling på JVM inneholder totalt 4 leksjoner.

Introduksjon til samtidighet og tilstand

Det er krevende å håndtere tilstand i samtidige programmer! Når flere deler av koden prøver å endre de samme dataene samtidig, kan De støte på store problemer som dataødeleggelse eller vranglåser.

Clojure tilbyr kraftige verktøy for å håndtere delt, muterbar tilstand på en trygg og effektiv måte.

Clojures filosofi for tilstand

Clojure bygger som standard på uforanderlighet. Det betyr at datastrukturer ikke endres etter at de er opprettet. Men hva gjør De når De faktisk trenger å endre noe, for eksempel en teller eller saldoen til en bruker?

  • Clojure tilbyr spesielle samtidighetsprimitiver.
  • Disse primitivene håndterer muterbar tilstand på en kontrollert måte.
  • De sørger for at endringer er trygge, også på tvers av flere tråder.

Atomer: uavhengig tilstand

Et Atom er den enkleste måten å håndtere ett enkelt, uavhengig stykke muterbar tilstand på. Det egner seg godt til ting som tellere eller flagg.

  • Oppdateringer er synkrone og atomiske (alt eller ingenting).
  • Atomer bruker en Compare-And-Swap-løkke (CAS) internt.
  • Best egnet for tilstand som ikke trenger å koordineres med andre tilstandsdata.

Kodeeksempel med Atom

La oss se et Atom i praksis. Vi oppretter en enkel teller og oppdaterer den.

(ns coddykit.core
  (:gen-class))

(defn -main
  "Demonstrates Clojure Atoms."
  [& args]
  (let [my-counter (atom 0)]
    (println "Initial value:" @my-counter)

    (swap! my-counter inc)
    (println "After inc:" @my-counter)

    (swap! my-counter + 5)
    (println "After add 5:" @my-counter)))

`swap!` for Atom forklart

Funksjonen swap! er sentral for oppdatering av Atomer:

  • Den tar atomet, en funksjon og valgfrie argumenter til funksjonen.
  • (swap! my-atom inc) øker verdien atomisk.
  • (swap! my-atom + 5) legger atomisk 5 til verdien.
  • Funksjonen brukes på atomets gjeldende verdi, og resultatet blir den nye verdien. Dette skjer på en trådsikker måte.

Refs: koordinert tilstand

Refs brukes til å håndtere koordinert muterbar tilstand. Det betyr at De har flere tilstandsdata som må endres sammen, eller ikke endres i det hele tatt.

  • Refs bruker Clojures Software Transactional Memory (STM).
  • Endringer skjer innenfor en transaksjon (en dosync-blokk).
  • Alle endringer i en transaksjon lykkes eller mislykkes som en samlet enhet.

Kodeeksempel med Ref

Slik bruker De Refs til å overføre en verdi atomisk mellom to kontoer. Hvis én operasjon mislykkes, rulles begge tilbake.

(ns coddykit.core
  (:gen-class))

(defn -main
  "Demonstrates Clojure Refs and STM."
  [& args]
  (let [account-a (ref 100)
        account-b (ref 50)
        amount-to-transfer 20]

    (println "Initial: A=" @account-a "B=" @account-b)

    (dosync
      (alter account-a - amount-to-transfer)
      (alter account-b + amount-to-transfer))

    (println "After transfer: A=" @account-a "B=" @account-b)))

STM med Refs forklart

dosync-blokken definerer en transaksjon:

  • ref oppretter en ny Ref.
  • alter endrer verdien til en Ref i en transaksjon. Den tar Ref-en, en funksjon og argumentene til funksjonen.
  • Hvis en del av dosync-blokken mislykkes, rulles alle endringer tilbake.
  • Dette sikrer atomisitet: alt eller ingenting.

Agenter: asynkron tilstand

Agenter er utviklet for å håndtere muterbar tilstand asynkront og isolert. De egner seg perfekt til oppgaver som kan ta tid eller kjøre i bakgrunnen uten å blokkere hovedtråden.

  • Oppdateringer sendes som meldinger til agenten.
  • Agenten behandler disse meldingene i en separat tråd.
  • Dette gir isolasjon: Agentens tilstand endres bare gjennom agentens egen behandling.

Kodeeksempel med agent

La oss bruke en agent til å behandle en liste med tall asynkront og summere dem.

(ns coddykit.core
  (:gen-class))

(defn -main
  "Demonstrates Clojure Agents."
  [& args]
  (let [sum-agent (agent 0)]
    (println "Initial sum:" @sum-agent)

    (send sum-agent + 10)
    (send sum-agent + 20)
    (send sum-agent + 5)

    (println "Waiting for agent to finish...")
    (await sum-agent) ; Wait for all sent actions to complete
    
    (println "Final sum:" @sum-agent)))

Arbeidsflyt for agenter

Slik fungerer agenter:

  • agent oppretter en ny agent med en startverdi.
  • send sender en funksjon og argumenter til agenten. Funksjonen brukes på agentens nåværende tilstand i en annen tråd.
  • Agenten behandler meldinger én etter én i sin egen tråd, noe som sikrer isolerte oppdateringer.
  • await (eller await-for) brukes til å blokkere den aktuelle tråden til agenten har behandlet alle ventende handlinger.

Velge riktig primitiv

De har lært om Atoms, Refs og Agents. Hver av dem har et bestemt formål for trygg håndtering av muterbar tilstand.

Hvilke av følgende påstander beskriver riktig når de ulike samtidighetsprimitivene skal brukes?

Oppsummering: Tilstandshåndtering

I denne leksjonen utforsket vi Clojures sentrale samtidighetsprimitiver for trygg håndtering av muterbar tilstand:

  • Atoms: For enkle, uavhengige og synkrone tilstandsendringer.
  • Refs: For koordinerte, transaksjonelle tilstandsendringer på tvers av flere verdier ved hjelp av STM.
  • Agents: For asynkrone og isolerte tilstandsoppdateringer som behandles i en separat tråd.

Det er avgjørende å forstå disse verktøyene for å kunne bygge robuste og samtidige Clojure-applikasjoner!

Gratis å komme i gang

Lær deg Clojure med en AI-veileder – gratis

Skriv og kjør ekte kode i nettleseren, få umiddelbar hjelp fra en AI-veileder som er tilgjengelig døgnet rundt, og fortsett der du slapp – på nettet eller i appen.

Kurs
12
Leksjoner
48

Ofte stilte spørsmål

Er leksjonen «Refs, agenter og atomer for tilstand» gratis?

Ja – hele teksten i «Refs, agenter og atomer for tilstand» er gratis å lese her på nettet. For å øve interaktivt med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt, og for å låse opp resten av Clojure: funksjonell programmering og backendutvikling på JVM-kurset, kan du oppgradere til CoddyKit PRO. Kurset i Clojure: funksjonell programmering og backendutvikling på JVM inneholder totalt 4 leksjoner.

Hva lærer jeg i «Refs, agenter og atomer for tilstand»?

Lær å bruke Clojures grunnleggende primitiver for samtidighet til å håndtere endringsbar tilstand trygt på tvers av tråder. Du øver på Clojure: funksjonell programmering og backendutvikling på JVM med praktisk kode som du kjører direkte i nettleseren, mens en AI-veileder som er tilgjengelig døgnet rundt, svarer på spørsmålene dine mens du jobber deg gjennom leksjonen.

Trenger jeg erfaring for å begynne med Clojure: funksjonell programmering og backendutvikling på JVM?

Ingen tidligere erfaring er nødvendig. Clojure: funksjonell programmering og backendutvikling på JVM på CoddyKit er lagt opp for både nybegynnere og viderekomne, så De kan begynne her eller helt fra start og lære i Deres eget tempo. Dette er leksjon 1 av 4.

Hvor lang tid tar leksjonen «Refs, agenter og atomer for tilstand»?

De fleste CoddyKit-leksjoner tar omtrent 5–10 minutter. Hver leksjon er kort og interaktiv, slik at De gjør jevne fremskritt og kan fortsette akkurat der De slapp – både på nettet og i appen.

Kan jeg skrive og kjøre kode i denne Clojure: funksjonell programmering og backendutvikling på JVM-leksjonen?

Ja. Alle Clojure: funksjonell programmering og backendutvikling på JVM-leksjoner har en innebygd kodeeditor, slik at De kan skrive og kjøre ekte kode direkte i nettleseren og få umiddelbar tilbakemelding fra AI – uten lokal konfigurering.

Alle leksjonene i dette kurset

  1. Refs, agenter og atomer for tilstand
  2. Software Transactional Memory (STM)
  3. Promises, futures og asynkrone operasjoner
  4. core.async-kanaler og go-blokker
← Tilbake til Clojure: funksjonell programmering og backendutvikling på JVM