Kako Java virtualni stroj vrši sinkronizaciju niti

Svi su Java programi kompajlirani u datoteke klase, koje sadrže bajt kodove, strojni jezik Java virtualnog stroja. Ovaj će članak pogledati kako Java virtualni stroj upravlja sinkronizacijom niti, uključujući relevantne bajtkodove. (1.750 riječi)

Ovomjesečni Under The Hood bavi se sinkronizacijom niti u Java jeziku i Java virtualnom stroju (JVM). Ovaj je članak posljednji u nizu članaka bytecode-a koje sam započeo prošlog ljeta. Opisuje jedina dva opkodova izravno povezana s sinkronizacijom niti, opcode koji se koriste za ulazak i izlaz iz monitora.

Niti i zajednički podaci

Jedna od prednosti programskog jezika Java je podrška za multithreading na razini jezika. Većina ove podrške usmjerena je na koordinaciju pristupa podacima koji se dijele između više niti.

JVM organizira podatke pokrenute Java aplikacije u nekoliko runtime podatkovnih područja: jedan ili više Java snopova, hrpa i područje metode. Za pozadinu na tim memorijskim područjima pogledajte prvi članak Under the Hood : "Mršav, znači virtualni stroj."

Unutar Java virtualnog stroja svaka nit dobiva Java stog koji sadrži podatke kojima niti jedna nit ne može pristupiti, uključujući lokalne varijable, parametre i povratne vrijednosti svake metode koju je nit pozvala. Podaci na stogu ograničeni su na primitivne tipove i reference na objekt. U JVM-u nije moguće postaviti sliku stvarnog objekta na stog. Svi se predmeti nalaze na hrpi.

Unutar JVM-a postoji samo jedna hrpa i sve je niti dijele. Hrpa ne sadrži ništa osim predmeta. Na hrpu ne postoji način da se osamljeni primitivni tip ili referenca na objekt postave - te stvari moraju biti dio objekta. Nizovi se nalaze na hrpi, uključujući nizove primitivnih tipova, ali u Javi su nizovi također objekti.

Osim Java snopa i hrpe, podaci o ostalim mjestima mogu se nalaziti u JVM-u je područje metode , koje sadrži sve varijable klase (ili statičke) koje koristi program. Područje metode slično je stogu po tome što sadrži samo primitivne tipove i reference na objekt. Međutim, za razliku od stoga, varijable klase u području metode dijele sve niti.

Brave predmeta i klase

Kao što je gore opisano, dva memorijska područja na Java virtualnom stroju sadrže podatke koje dijele sve niti. Ovi su:

  • Hrpa koja sadrži sve predmete
  • Područje metode, koje sadrži sve varijable klase

Ako više niti istovremeno mora koristiti iste objekte ili varijable klase, njihovim pristupom podacima mora se pravilno upravljati. Inače, program će se nepredvidljivo ponašati.

Za koordinaciju zajedničkog pristupa podacima između više niti, Java virtualni stroj pridružuje zaključavanje svakom objektu i klasi. Brava je poput privilegija koju samo jedna nit može istovremeno posjedovati. Ako nit želi zaključati određeni objekt ili klasu, pita JVM. U nekom trenutku nakon što nit zatraži od JVM-a bravu - možda vrlo brzo, možda kasnije, možda nikad - JVM daje bravu niti. Kada nit više ne treba bravu, vraća je JVM-u. Ako je druga nit zatražila isto zaključavanje, JVM prenosi zaključavanje toj niti.

Brave klase zapravo su implementirane kao objektne brave. Kada JVM učita datoteku klase, stvara instancu klase java.lang.Class. Kada zaključate klasu, zapravo zaključavate Classobjekt te klase .

Teme ne moraju dobiti zaključavanje za pristup varijablama instance ili klase. Međutim, ako nit dobije zaključavanje, niti jedna druga nit ne može pristupiti zaključanim podacima dok ih nit koja je u vlasništvu brave ne oslobodi.

Monitori

JVM koristi brave zajedno s monitorima . Monitor je u osnovi čuvar po tome što nadgleda slijed koda, pazeći da samo jedna nit istovremeno izvršava kôd.

Svaki je monitor povezan s referencom objekta. Kad nit stigne do prve upute u bloku koda koji je pod budnim okom monitora, nit mora dobiti zaključavanje na referenciranom objektu. Nit ne smije izvršavati kôd dok ne dobije zaključavanje. Jednom kada dobije zaključavanje, nit ulazi u blok zaštićenog koda.

Kad nit napusti blok, bez obzira kako napušta blok, oslobađa bravu na pridruženom objektu.

Višestruke brave

Jedna nit smije zaključati isti objekt više puta. Za svaki objekt JVM održava brojanje koliko je puta objekt zaključan. Otključani objekt broji nulu. Kada nit prvi put dobije zaključavanje, broj se povećava na jedan. Svaki put kada nit dobije zaključavanje na istom objektu, broj se povećava. Svaki put kada nit otpusti bravu, broj se smanjuje. Kad broj dosegne nulu, brava se otpušta i stavlja na raspolaganje ostalim nitima.

Sinkronizirani blokovi

U terminologiji Java jezika, koordinacija više niti koje moraju pristupiti zajedničkim podacima naziva se sinkronizacija . Jezik nudi dva ugrađena načina za sinkronizaciju pristupa podacima: sinkroniziranim izrazima ili sinkroniziranim metodama.

Sinkronizirane izjave

Da biste stvorili sinkronizirani izraz, koristite synchronizedključnu riječ s izrazom koji procjenjuje na referencu objekta, kao u reverseOrder()donjoj metodi:

class KitchenSync { private int[] intArray = new int[10]; void reverseOrder() { synchronized (this) { int halfWay = intArray.length / 2; for (int i = 0; i < halfWay; ++i) { int upperIndex = intArray.length - 1 - i; int save = intArray[upperIndex]; intArray[upperIndex] = intArray[i]; intArray[i] = save; } } } }

U gore navedenom slučaju, izrazi sadržani u sinkroniziranom bloku neće se izvršavati dok se ne zaključa zaključak trenutnog objekta ( this). Ako umjesto thisizraza referenca daje referencu na drugi objekt, zaključavanje povezano s tim objektom dobiva se prije nastavka niti.

Two opcodes, monitorenter and monitorexit, are used for synchronization blocks within methods, as shown in the table below.

Table 1. Monitors

Opcode Operand(s) Description
monitorenter none pop objectref, acquire the lock associated with objectref
monitorexit none pop objectref, release the lock associated with objectref

When monitorenter is encountered by the Java virtual machine, it acquires the lock for the object referred to by objectref on the stack. If the thread already owns the lock for that object, a count is incremented. Each time monitorexit is executed for the thread on the object, the count is decremented. When the count reaches zero, the monitor is released.

Take a look at the bytecode sequence generated by the reverseOrder() method of the KitchenSync class.

Note that a catch clause ensures the locked object will be unlocked even if an exception is thrown from within the synchronized block. No matter how the synchronized block is exited, the object lock acquired when the thread entered the block definitely will be released.

Synchronized methods

To synchronize an entire method, you just include the synchronized keyword as one of the method qualifiers, as in:

class HeatSync { private int[] intArray = new int[10]; synchronized void reverseOrder() { int halfWay = intArray.length / 2; for (int i = 0; i < halfWay; ++i) { int upperIndex = intArray.length - 1 - i; int save = intArray[upperIndex]; intArray[upperIndex] = intArray[i]; intArray[i] = save; } } }

The JVM does not use any special opcodes to invoke or return from synchronized methods. When the JVM resolves the symbolic reference to a method, it determines whether the method is synchronized. If it is, the JVM acquires a lock before invoking the method. For an instance method, the JVM acquires the lock associated with the object upon which the method is being invoked. For a class method, it acquires the lock associated with the class to which the method belongs. After a synchronized method completes, whether it completes by returning or by throwing an exception, the lock is released.

Coming next month

Now that I have gone through the entire bytecode instruction set, I will be broadening the scope of this column to include various aspects or applications of Java technology, not just the Java virtual machine. Next month, I'll begin a multi-part series that gives an in-depth overview of Java's security model.

Bill Venners profesionalno piše softver već 12 godina. Sa sjedištem u Silicijskoj dolini pruža usluge savjetovanja i obuke za softver pod nazivom Artima Software Company. Tijekom godina razvio je softver za potrošačku elektroniku, obrazovanje, poluvodiče i industriju životnog osiguranja. Programirao je na mnogim jezicima na mnogim platformama: montažni jezik na raznim mikroprocesorima, C na Unixu, C ++ na Windowsima, Java na webu. Autor je knjige: Inside Java Virtual Machine, u izdanju McGraw-Hill.

Saznajte više o ovoj temi

  • The book The Java virtual machine Specification (//www.aw.com/cp/lindholm-yellin.html), by Tim Lindholm and Frank Yellin (ISBN 0-201-63452-X), part of The Java Series (//www.aw.com/cp/javaseries.html), from Addison-Wesley, is the definitive Java virtual machine reference.
  • Previous "Under The Hood" articles:
  • "The Lean, Mean Virtual Machine" Gives an introduction to the Java virtual machine.
  • "The Java Class File Lifestyle" Gives an overview to the Java class file, the file format into which all Java programs are compiled.
  • "Java's Garbage-Collected Heap" Gives an overview of garbage collection in general and the garbage-collected heap of the Java virtual machine in particular.
  • "Bytecode Basics" Introduces the bytecodes of the Java virtual machine, and discusses primitive types, conversion operations, and stack operations in particular.
  • "Floating Point Arithmetic" Describes the Java virtual machine's floating-point support and the bytecodes that perform floating point operations.
  • "Logic and Arithmetic" Describes the Java virtual machine's support for logical and integer arithmetic, and the related bytecodes.
  • "Objects and Arrays" Describes how the Java virtual machine deals with objects and arrays, and discusses the relevant bytecodes.
  • "Exceptions" Describes how the Java virtual machine deals with exceptions, and discusses the relevant bytecodes.
  • "Probaj konačno" Opisuje kako Java virtualni stroj implementira klauzule pokušaj konačno i raspravlja o relevantnim bajt kodovima.
  • "Kontrolni tok" Opisuje kako Java virtualni stroj implementira kontrolni tok i razmatra relevantne bajt kodove.
  • "Arhitektura Agletsa" opisuje unutarnji rad Agletsa, IBM-ove autonomne tehnologije softverskog agenta zasnovanog na Javi.
  • "The Point of Aglets" analizira stvarnu korisnost mobilnih agenata kao što je Aglets, IBM-ova autonomna tehnologija softverskog agenta zasnovana na Javi.
  • "Pozivanje i povratak metode" Objašnjava kako se virtualni stroj Java poziva i vraća iz metoda, uključujući relevantne bajt kodove.

Ovu je priču "Kako Java virtualni stroj vrši sinkronizaciju niti" izvorno objavio JavaWorld.