Java Memory Model ( JMM ) beskriver beteendet hos trådar i Java runtime-miljön . Minnesmodellen är en del av Java-språkets semantik , och beskriver vad en programmerare kan och inte bör förvänta sig när man utvecklar programvara inte för en specifik Java-maskin, utan för Java som helhet.
Den ursprungliga Java-minnesmodellen (som inkluderar "perkolokalt minne" i synnerhet), utvecklad 1995, anses vara ett misslyckande: många optimeringar kan inte göras utan att förlora garantin för kodsäkerhet. I synnerhet finns det flera alternativ för att skriva flertrådiga " enhands ": [1]
J2SE 5.0 ( 30 september 2004) introducerade en ny minnesmodell utvecklad genom Java Community Process kallad JSR-133 [2] [3] . Det återspeglade bättre hur moderna processorer och kompilatorer fungerar, och andra språk har hämtat idéer från Java-modellen. De viktigaste bidragen till dess skapelse gjordes av Sarita Adwe , Jeremy Mason och Bill Pugh [4] .
Programmeringsspråket Java låter dig skriva flertrådade program. Eftersom Java kan köras på en mängd olika processorer och operativsystem är trådsynkronisering särskilt svårt. För att programmeraren skulle kunna dra några slutsatser om programmens beteende, bestämde sig Java-utvecklarna för att tydligt definiera de olika beteendena för alla Java-program.
På moderna datorer exekveras koden inte i den ordning som den skrivs för hastighetens skull. Permutationen görs av kompilatorn, processorn och minnesundersystemet. På multiprocessormaskiner kan varje kärna ha sin egen cache som inte är synkron med huvudminnet. Det betyder att olika processorer kan ha olika värden på samma variabel samtidigt. När trådar interagerar mycket med varandra är detta vanligtvis oönskat: det tar mycket tid att hålla sig à jour med vad den andra processorn har gjort.
Dessutom, i en enkeltrådad miljö, räcker det att kräva att systemet ska "pseudo-sekventiell" programkörning - för en observatör som bara ser I/O , kommer det att verka som att alla åtgärder utförs i den ordning som de dykt upp i programmet, även om de inte är det. Den som kan "titta" i datorns minne - inklusive en annan tråd - kommer dock att märkas av alla dessa "tricks". Tänk på två trådar som samtidigt exekverar sådan kod ( xoch yinitialt nollor).
Streama 1 | Streama 2 |
---|---|
x = 1; | int rl = y; |
y=2; | int r2 = x; |
Om det inte finns några permutationer, och tråd 2 läser y=2, är det garanterat x=1: trots allt, skrivningen till xutförs innan skrivningen till y. Med en permutation visar sig en till synes paradoxal situation vara möjlig: r1=2, r2=0.
JMM tillåter detta beteende för flertrådade program, men beskriver när sådana permutationer är möjliga. Java-minnesmodellen lägger alltså restriktioner på interaktionen mellan trådar för att inte förlora möjliga optimeringar och samtidigt tillåta flertrådade program att bete sig tillförlitligt och förutsägbart där det behövs. Programmeraren kan göra vilka slutsatser som helst om i vilken ordning koden exekveras på en flertrådad maskin, även trots de optimeringar som gjorts av kompilatorn, processorn och cachen.
Regel #1: Enkeltrådade program körs pseudo-sekventiellt. Detta betyder: i verkligheten kan processorn utföra flera operationer per klocka, samtidigt som de ändrar sin ordning, men alla databeroenden kvarstår, så beteendet skiljer sig inte från sekventiellt.
Regel nummer 2: det finns inga värden från ingenstans. Att läsa valfri variabel (förutom icke- volatile longoch double, för vilka denna regel kanske inte är sann) returnerar antingen standardvärdet (noll) eller något som skrivits där av ett annat kommando.
Och regel nummer 3: resten av händelserna exekveras i ordning, om de är sammankopplade med ett strikt partiell ordningsförhållande "utförs före" ( engelska händer före ).
"Happens before" ( engelska happens before ) är en strikt partiell ordningsrelation (antireflexiv, antisymmetrisk, transitiv) införd mellan atomiska kommandon ( ++och --inte atomiska), uppfunnen av Leslie Lamport och betyder inte "fysiskt innan". Det betyder att det andra laget kommer att vara "medvetet" om ändringarna som gjorts av det första.
I synnerhet utförs den ena före den andra för sådana operationer (listan är inte uttömmande):
På grund av den utbredda introduktionen av flertrådiga och parallella system krävdes en verktygslåda med tydlig semantik. Java-minnesmodellen var det första försöket att utveckla en omfattande kommunikationsmodell mellan trådar för ett stort programmeringsspråk [9] .
I C++03 är den enda anmärkningen om multithreading att volatile-variabler inte har några accesshastighetsoptimeringar. Detta räckte inte heller för att använda den fulla kraften hos den omarrangerande kompilatorn/processorn och inte få ett fel relaterat till att ett kommando utfördes i oordning. En liknande minnesmodell inkluderades i C++11 [10] .
Java | |
---|---|
Plattformar | |
Sun Technologies | |
Viktiga tredjepartstekniker | |
Berättelse |
|
Språkegenskaper | |
Skriptspråk |
|
Java-konferenser |
|