Het is mogelijk dat meerdere jobs in het systeem toegang tot hetzelfde object moeten hebben. Met ILock wordt een protocol gedefinieerd voor het verlenen van exclusieve toegang tot een gedeeld object. Als een job toegang tot een gemeenschappelijk object nodig heeft, vraagt de job een vergrendeling van het object aan. Als de bewerking van het object gereed is, wordt de vergrendeling weer opgeheven.
Een vergrendeling wordt normaal gemaakt als het gemeenschappelijk object wordt gemaakt of als een plugin voor het eerst toegang krijgt. Code met een verwijzing naar het gemeenschappelijke object bevat ook een verwijzing naar de vergrendeling. Het voorbeeld begint met een vergrendeling, genaamd myLock, die wordt gebruikt om de toegang tot myObject te beheren:
... myObject = initializeImportantObject(); IJobManager jobMan = Platform.getJobManager(); myLock = jobMan.newLock(); ...
Het platform biedt een krachtige implementatie van ILock. De jobmanager biedt instances van deze vergrendeling aan voor gebruik door clients. Deze vergrendelingen zijn van elkaar op de hoogte en zorgen dat er slechts één vergrendeling actief is. (Later volgt hierover meer uitleg.)
Als de code in een job toegang tot myObject nodig heeft, moet het object eerst worden vergrendeld. In het volgende voorbeeld ziet u een gebruikelijke code voor het werken met een vergrendeling:
... // Ik moet myObject bewerken, dus ik maak eerst een vergrendeling. try { myLock.acquire(); updateState(myObject); // object bewerken } finally { lock.release(); } ...
De methode acquire() stuurt pas een retourwaarde als de aanroepende job exclusieve toegang tot de vergrendeling kan krijgen. Met andere woorden, als een andere job al een vergrendeling heeft aangevraagd, wordt de code geblokkeerd tot de vergrendeling beschikbaar is. De code die de vergrendeling krijgt en myObject bewerkt, is opgenomen in een try-blok, zodat de vergrendeling kan worden vrijgegeven als er uitzonderingen optreden tijdens het werken met het object.
Dit werkt allemaal vrij eenvoudig. Het is gelukkig eenvoudig om met vergrendelingen te werken. Ze zijn ook opnieuw toegankelijk, zodat u zich geen zorgen hoeft te maken als uw job dezelfde vergrendeling meerdere malen moet aanvragen. Iedere vergrendeling houdt bij hoe vaak deze wordt aangevraagd en vrijgegeven voor een bepaalde thread. De vergrendeling voor een job wordt alleen vrijgegeven als het aantal vrijgevingen gelijk is aan het aantal aanvragen.
U hebt eerder gezien dat vergrendelingen van de jobmanager elkaar kennen en kunnen voorkomen dat de bewerking door een conflict vastloopt. Om te begrijpen hoe een conflict ontstaat, kijken we naar een eenvoudig scenario. Stel dat "Job A" "Vergrendeling A" aanvraagt en vervolgens probeert "Vergrendeling B" te verkrijgen. Tegelijkertijd is "Vergrendeling B" in gebruik door "Job B" en geblokkeerd in afwachting van "Vergrendeling A". Dit soort conflictbeveiliging houdt verband met een onderliggend ontwerpprobleem bij het gebruik van vergrendelingen tussen jobs. Simpele gevallen als dit kunnen eenvoudig worden vermeden, maar de kansen op een conflict nemen toe als het aantal jobs en vergrendelingen in uw ontwerp toeneemt.
Gelukkig help het platform bij het opsporen van conflicten. Als de jobmanager een conflict detecteert, schrijft deze diagnostische informatie in het logboek en een beschrijving van het conflict. Vervolgens wordt het conflict opgelost door jobs tijdelijk toegang te verschaffen tot de vergrendelingen die eigendom zijn van een geblokkeerde job. Het is belangrijk om een implementatie met meerdere vergrendelingen uitgebreid te testen en conflicten op te lossen die door het platform zijn gemeld.