Synchronisering i Java
Vad รคr Synchronisering i Java?
In Java, synkronisering syftar pรฅ mรถjligheten att kontrollera รฅtkomsten av flera trรฅdar till valfri delad resurs. Det รคr ett idealiskt alternativ dรคr vi vill tillรฅta endast en trรฅd att komma รฅt den delade resursen.
Detta tillvรคgagรฅngssรคtt fรถr exekvering brukar kallas "asynkron" programmering. Det finns ocksรฅ trรฅdar om dessa processorer, som รคr lรคtta processer som kan exekvera instruktioner samtidigt.
Typer av Synchronisering
Det finns tvรฅ typer av synkroniseringsmetoder i Java:
1) Processsynkronisering
2) Trรฅdsynkronisering.
Lรฅt oss studera trรฅd och Processsynkronisering i detalj.
Processsynkronisering: Den hanterar synkronisering mellan program. Till exempel program som `Microsoft Word` och `Acrobat reader` kรถrs som individuella processer.
Trรฅdsynkronisering: Den samtidiga exekveringen av den kritiska resursen av tvรฅ eller flera trรฅdar kallas trรฅd Synchronisering. Du kan grupperas ytterligare fรถr att รถmsesidigt utesluta och kommunikation mellan trรฅdar.
Vad รคr Lock in Java?
Lรฅsa in Java รคr byggd kring en intern enhet som kallas en monitor eller lรฅset. Alla objekt har ett lรฅs kopplat till dem. Sรฅ trรฅden som behรถver konsekvent รฅtkomst till ett objekts fรคlt mรฅste skaffa objektets lรฅs innan den kommer รฅt dem, och den slรคpper lรฅset nรคr arbetet รคr klart. Detta sรคkerstรคller att endast en trรฅd kommer รฅt de delade data รฅt gรฅngen.
Flertrรฅdigt program med synkronisering
Ett flertrรฅdigt program รคr en metod eller ett block som รคr skyddat frรฅn stรถrningar frรฅn andra trรฅdar som delar samma resurs som anges med nyckelordet "synkroniserat".
Anvรคnder den synkroniserade metoden
Varje metod som deklareras som synkroniserad รคr kรคnd som en synkroniserad metod. Det anvรคnds ocksรฅ fรถr att lรฅsa ett objekt fรถr alla delade resurser. Sรฅ, nรคr en trรฅd anropar en synkroniserad metod. Den tar automatiskt besittning av lรฅset fรถr det objektet och slรคpper det nรคr det har avslutat sin uppgift.
Obs: Det synkroniserade nyckelordet kan inte fungera med klasser och variabler. Endast metoder och block kan anvรคndas med nyckelordet.
Varfรถr anvรคnda Synchroniserad metod?
- Den anvรคnds fรถr att lรฅsa ett objekt fรถr alla delade resurser.
- Objektet fรฅr lรฅset nรคr den synkroniserade metoden anropas.
- Lรฅset slรคpper inte fรถrrรคn trรฅden slutfรถrt sin funktion
Syntax:
Acess_modifiers synchronized return_type method_name (Method_Parameters) {
}
class MathService {
synchronized void getSumOfArray(int[] numbers) {
int sum = 0;
for (int number : numbers) {
System.out.println(Thread.currentThread()
.getName()
+ " adds "
+ sum + " to "
+ number + " to get -> "
+ (sum += number));
try {
Thread.sleep(500);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
}
public class Synchronization {
public static void main(String[] args) {
MathService mathService = new MathService();
Thread threadOne = new Thread(() ->
mathService.getSumOfArray(new int[]{10, 11, 12}));
Thread threadTwo = new Thread(() ->
mathService.getSumOfArray(new int[]{20, 21, 22}));
threadOne.start();
threadTwo.start();
}
}
Fรถrklaring till Code:
Kรถr det hรคr exemplet och observera att trรฅden `0` fรฅr lรฅset fรถr `mathService`-objektet fรถrst och anvรคnder detta lรฅs exklusivt tills den har slutfรถrt exekveringen. Trรฅd "0" och "1" รคr inte interfolierade i denna kod. Utgรฅngen รคr som visas nedan.
Produktion:
Thread-0 adds 0 to 10 to get -> 10 Thread-0 adds 10 to 11 to get -> 21 Thread-0 adds 21 to 12 to get -> 33 Thread-1 adds 0 to 20 to get -> 20 Thread-1 adds 20 to 21 to get -> 41 Thread-1 adds 41 to 22 to get -> 63
Anvรคnder ett synkroniserat block
Lรฅt oss anta att du inte vill synkronisera hela metoden. Istรคllet vill du synkronisera nรฅgra rader kod. Pรฅ den tiden, den Synchronized block hjรคlpte till att synkronisera det valda Java koda. Synchroniserade metodlรฅs nรฅs pรฅ metoden, medan synkroniserade blocklรฅs nรฅs pรฅ objektet.
class MathService {
void getSumOfArray(int[] numbers) {
synchronized (this){
int sum = 0;
for (int number : numbers) {
System.out.println(Thread.currentThread()
.getName()
+ " adds "
+ sum + " to "
+ number + " to get -> "
+ (sum += number));
try {
Thread.sleep(500);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
}
}
public class Synchronization {
public static void main(String[] args) {
MathService mathService = new MathService();
Thread threadOne = new Thread(() ->
mathService.getSumOfArray(new int[]{10, 11, 12}));
Thread threadTwo = new Thread(() ->
mathService.getSumOfArray(new int[]{20, 21, 22}));
threadOne.start();
threadTwo.start();
}
}
Code Fรถrklaring:
Nรคr du kรถr den hรคr koden kommer du att notera att den fungerar utan stรถrningar. I den synkroniserade metoden tillรคmpas lรฅset av metoden, men i det synkroniserade blocket tillรคmpas lรฅset av objektet. Se till att utgรฅngen รคr som visas nedan.
Produktion:
Thread-0 adds 0 to 10 to get -> 10 Thread-0 adds 10 to 11 to get -> 21 Thread-0 adds 21 to 12 to get -> 33 Thread-1 adds 0 to 20 to get -> 20 Thread-1 adds 20 to 21 to get -> 41 Thread-1 adds 41 to 22 to get -> 63
Fรถrklaring av kod:
Nรคr du kรถr den hรคr koden kommer du att notera att den fungerar utan stรถrningar, vilket vi fรถrvรคntade oss. I den synkroniserade metoden tillรคmpas lรฅset av metoden, men i den synkroniserade blockmetoden tillรคmpas lรฅset av objektet.
Anvรคnder statisk synkronisering
In Java synkronisering, om det finns mer รคn ett objekt, kan tvรฅ trรฅdar fรถrvรคrva lรฅsen och gรฅ in i ett synkroniserat block eller block, med ett separat lรฅs fรถr varje objekt. Fรถr att undvika detta kan statisk synkronisering anvรคndas. Synchroniserade nyckelord kommer att anvรคndas fรถre statiska metoder.
Obs: I statisk synkronisering รคr lรฅsรฅtkomst pรฅ klassen, inte objektet och metoden.
Code fรถr att demonstrera problemet med att flera objekt lรฅser sig
class MathService {
synchronized void getSumOfArray(int[] numbers) {
int sum = 0;
for (int number : numbers) {
System.out.println(Thread.currentThread()
.getName()
+ " adds "
+ sum + " to "
+ number + " to get -> "
+ (sum += number));
try {
Thread.sleep(500);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
}
public class Synchronization {
public static void main(String[] args) {
MathService mathService = new MathService();
MathService mathService1 = new MathService();
Thread threadOne = new Thread(() ->
mathService.getSumOfArray(new int[]{10, 11, 12}));
Thread threadTwo = new Thread(() ->
mathService.getSumOfArray(new int[]{20, 21, 22}));
Thread threadThree = new Thread(() ->
mathService1.getSumOfArray(new int[]{10, 11, 12}));
Thread threadFour = new Thread(() ->
mathService1.getSumOfArray(new int[]{20, 21, 22}));
threadOne.start();
threadTwo.start();
threadThree.start();
threadFour.start();
}
}
Fรถrklaring av kod:
Nรคr vi skapar en annan instans av `MathService` introducerar vi interferens i trรฅdarna eftersom de kommer att interfolieras med de tvรฅ objekten. Observera att trรฅd `0` och trรฅd `2` รคr sammanflรคtade med de tvรฅ objekten, medan trรฅd `1` och `3` รคr sammanflรคtade med de tvรฅ objekten.
Produktion:
Thread-0 adds 0 to 10 to get -> 10 Thread-2 adds 0 to 10 to get -> 10 Thread-0 adds 10 to 11 to get -> 21 Thread-2 adds 10 to 11 to get -> 21 Thread-0 adds 21 to 12 to get -> 33 Thread-2 adds 21 to 12 to get -> 33 Thread-1 adds 0 to 20 to get -> 20 Thread-3 adds 0 to 20 to get -> 20 Thread-1 adds 20 to 21 to get -> 41 Thread-3 adds 20 to 21 to get -> 41 Thread-1 adds 41 to 22 to get -> 63 Thread-3 adds 41 to 22 to get -> 63
Samma kod med synkroniserad statisk metod
class MathService {
synchronized static void getSumOfArray(int[] numbers) {
int sum = 0;
for (int number : numbers) {
System.out.println(Thread.currentThread()
.getName()
+ " adds "
+ sum + " to "
+ number + " to get -> "
+ (sum += number));
try {
Thread.sleep(500);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
}
public class Synchronization {
public static void main(String[] args) {
MathService mathService = new MathService();
MathService mathService1 = new MathService();
Thread threadOne = new Thread(() ->
mathService.getSumOfArray(new int[]{10, 11, 12}));
Thread threadTwo = new Thread(() ->
mathService.getSumOfArray(new int[]{20, 21, 22}));
Thread threadThree = new Thread(() ->
mathService1.getSumOfArray(new int[]{10, 11, 12}));
Thread threadFour = new Thread(() ->
mathService1.getSumOfArray(new int[]{20, 21, 22}));
threadOne.start();
threadTwo.start();
threadThree.start();
threadFour.start();
}
}
Kรถr ovanstรฅende kod och notera att vi nu har eliminerat trรฅdstรถrningar. Utdata frรฅn koden visas nedan.
Produktion:
Thread-0 adds 0 to 10 to get -> 10 Thread-0 adds 10 to 11 to get -> 21 Thread-0 adds 21 to 12 to get -> 33 Thread-3 adds 0 to 20 to get -> 20 Thread-3 adds 20 to 21 to get -> 41 Thread-3 adds 41 to 22 to get -> 63 Thread-2 adds 0 to 10 to get -> 10 Thread-2 adds 10 to 11 to get -> 21 Thread-2 adds 21 to 12 to get -> 33 Thread-1 adds 0 to 20 to get -> 20 Thread-1 adds 20 to 21 to get -> 41 Thread-1 adds 41 to 22 to get -> 63
Fรถrdelar med att anvรคnda synkronisering
Hรคr รคr fรถrdelarna med att arbeta med samtidiga applikationer:
- Huvudsyftet med synkronisering i Java รคr att fรถrhindra inkonsekventa data genom att fรถrhindra trรฅdstรถrningar.
- Det synkroniserade nyckelordet i Java tillhandahรฅller lรฅsning, vilket sรคkerstรคller รถmsesidigt uteslutande รฅtkomst till den delade resursen och fรถrhindrar dataracing.
- Det fรถrhindrar ocksรฅ omordning av kodsatser av kompilator, vilket kan orsaka ett subtilt samtidig problem om vi inte anvรคnder flyktiga eller synkroniserade sรถkord.
- Synchronized nyckelord lรคser data frรฅn huvudminnet รคn cache och nรคr det slรคpper lรฅset.
- Det rensar ocksรฅ skrivoperationer frรฅn huvudminnet, vilket eliminerar minnesinkonsekvensfel.
Nackdelar med Synchroniseringsmekanism
Synchronisering Mekanismer har dรฅlig prestanda.
Till exempel
- Antag att det finns fem processer, A1, A2, A3, A4 och A5.
- De vรคntar pรฅ att de delade resurserna ska komma รฅt en trรฅd i taget.
- Alla processer hรฅlls vรคntande, sรฅ den sista i kรถn mรฅste vรคnta tills alla andra processer รคr klara.
Sammanfattning
- Synchronisering hรคnvisar till mรถjligheten att kontrollera รฅtkomsten av flera trรฅdar till valfri delad resurs.
- Java har tvรฅ typer av synkroniseringsmetoder: 1) Processsynkronisering och 2) Trรฅdsynkronisering.
- Lรฅsa in Java รคr byggd kring en intern enhet som kallas en monitor eller lรฅset.
- Ett flertrรฅdigt program รคr en metod eller ett block som skyddas frรฅn stรถrningar frรฅn andra trรฅdar som delar samma resurs som anges med nyckelordet "synkroniserat".
- Varje metod som deklareras som synkroniserad รคr kรคnd som en synkroniserad metod.
- In Java, synkroniserade metodlรฅs nรฅs pรฅ metoden, medan synkroniserade blocklรฅs nรฅs pรฅ objektet.
- I statisk synkronisering รคr lรฅsรฅtkomst pรฅ klassen, inte objektet och metoden.
- Huvudsyftet med synkronisering i Java รคr att fรถrhindra inkonsekventa data genom att fรถrhindra trรฅdstรถrningar.
- Den stรถrsta nackdelen med denna metod รคr att alla processer hรฅlls i vรคntan, sรฅ den sista i kรถn mรฅste vรคnta tills alla andra processer รคr klara.
