Det kan hende at flere jobber i systemet trenger tilgang til og skal manipulere samme objekt. ILock definerer en protokoll for eksklusiv tilgang til et delt objekt. Når en jobb trenger tilgang til et slikt objekt, hentes en lås for objektet. Når jobben har manipulert ferdig et objekt, frigis låsen.
Vanligvis opprettes en lås når det delte objektet opprettes eller åpnes for første gang av en plugin-modul. Dette betyr at kode som har referanse til det delte objektet også inneholder en referanse til låsen. Vi starter med å opprette en lås, myLock, som brukes til å kontrollere tilgangen til myObject:
... myObject = initializeImportantObject(); IJobManager jobMan = Platform.getJobManager(); myLock = jobMan.newLock(); ...
Plattformen inneholder en kraftig implementering av ILock. Jobbstyreren inneholder forekomster av denne låsen som klienter kan bruke. Disse låsene er oppmerksomme på hverandre og kan unngå sirkulær vranglås. (Vi skal straks se nærmere på dette.)
Når koden i en jobb krever tilgang til myObject, må først låsen hentes. Følgende snutt viser et vanlig idiom for arbeid med låser:
... // I need to manipulate myObject, so I get its lock first. try { myLock.acquire(); updateState(myObject); // manipulate the object } finally { lock.release(); } ...
Metoden acquire() returnerer ingenting før kalljobben får eksklusiv tilgang til låsen. Dette betyr at hvis en annen jobb allerede har hentet låsen, blokkeres denne koden til låsen er tilgjengelig. Merk at koden som henter låsen og manipulerer myObject, pakkes i en try-blokk slik at låsen kan frigis hvis det oppstår unntak mens det arbeides på objektet.
Dette virker enkelt, ikke sant? Heldigvis er låser nokså enkle å bruke. De er også gjeninntredbare, noe som betyr at du slipper å tenke på at jobben skal hente samme lås flere ganger. Hver lås teller hvor mange ganger det hentes og frigis lås for en bestemt tråd, og frigis fra en jobb bare når antall frigivelser er likt antall låsinger.
Vi har tidligere sett at låser som er oppgitt av jobbstyreren, er oppmerksomme på hverandre og kan unngå sirkulær vranglås. For å forstå hvordan en vranglås oppstår, skal vi se på et enkelt scenario. Tenk deg at "Jobb A" henter "Lås A" og deretter forsøker å hente "Lås B". I mellomtiden er "Lås B" i "Jobb B", som nå er blokkert og venter på "Lås A". Slik vranglås antyder underliggende designproblemer med bruken av låser mellom jobber. Problemstillingen i dette enkle tilfellet kan unngås uten større problemer, men risikoen for at det ved en feiltakelse blir brukt vranglås, øker i takt med økende antall jobber og låser i bruk.
Heldigvis hjelper plattformen til med å identifisere vranglåser. Når jobbstyreren oppdager en vranglås, skriver den ut feilsøkingsinformasjon til loggen og beskriver vranglåssituasjonen. Deretter frigis vranglåsen ved å gi midlertidig tilgang til låsene som eies av en blokkert jobb, til andre jobber som venter. Det er viktig å gå forsiktig frem og teste implementering som involverer flere låser, og løse vranglåssituasjoner som rapporteres av plattformen.