Synchronisering i Java

Hvad er Synchronisering i Java?

In Java, synkronisering refererer til evnen til at kontrollere adgangen af ​​flere tråde til enhver delt ressource. Det er en ideel mulighed, hvor vi kun vil tillade én tråd at få adgang til den delte ressource.

Denne tilgang til udførelse omtales normalt som "asynkron" programmering. Der er også tråde på disse processorer, som er lette processer, der kan udføre instruktioner samtidigt.

Typer af Synchronisering

Der er to typer synkroniseringsmetoder i Java:

1) Processynkronisering

2) Trådsynkronisering.

Lad os studere tråd og Processynkronisering i detaljer.

Processynkronisering: Det styrer synkronisering mellem programmer. For eksempel programmer som `Microsoft Word` og `Acrobat reader` kører som individuelle processer.

Trådsynkronisering: Den samtidige udførelse af den kritiske ressource af to eller flere tråde kaldes tråd Synchronisering. Du kan grupperes yderligere til gensidigt udelukkende' og inter-trådskommunikation.

Hvad er Lock in Java?

Fastlåse Java er bygget op omkring en intern enhed kendt som en skærm eller låsen. Alle objekter har en lås forbundet med dem. Så tråden, der har brug for konsekvent adgang til et objekts felter, skal erhverve objektets lås, før den får adgang til dem, og den frigiver låsen, når arbejdet er færdigt. Dette sikrer, at kun én tråd får adgang til de delte data ad gangen.

Flertrådet program med synkronisering

Et flertrådet program er en metode eller blok, der er beskyttet mod interferens fra andre tråde, der deler den samme ressource angivet ved hjælp af nøgleordet `synkroniseret`.

Brug af den synkroniserede metode

Enhver metode, der er erklæret som synkroniseret, er kendt som en synkroniseret metode. Det bruges også til at låse et objekt for enhver delt ressource. Så når en tråd påberåber sig en synkroniseret metode. Den tager automatisk låsen til det pågældende objekt i besiddelse og frigiver den, når den er færdig med sin opgave.

Bemærk: Det synkroniserede nøgleord kan ikke fungere med klasser og variabler. Kun metoder og blokke kan bruges med søgeordet.

Hvorfor bruge Synchroniseret metode?

  • Det bruges til at låse et objekt for alle delte ressourcer.
  • Objektet får låsen, når den synkroniserede metode kaldes.
  • Låsen udløses ikke, før tråden fuldfører sin funktion

Syntaks:

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();
    }
}

Forklaring af kode:

Kør dette eksempel og observer, at tråden '0' får låsen til 'mathService'-objektet først og udelukkende bruger denne lås, indtil den er fuldført. Tråd "0" og "1" er ikke indflettet i denne kode. Udgangen er som vist nedenfor.

Output:

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

Brug af en synkroniseret blok

Lad os antage, at du ikke ønsker at synkronisere hele metoden. I stedet vil du synkronisere et par linjer kode. På det tidspunkt var Synchroniseret blok hjalp med at synkronisere den valgte Java kode. SyncDer er adgang til hroniserede metodelåse på metoden, hvorimod synkroniserede bloklåse tilgå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();
    }
}

Kodeforklaring:

Når du kører denne kode, vil du bemærke, at den fungerer uden forstyrrelser. I den synkroniserede metode anvendes låsen af ​​metoden, men i den synkroniserede blok anvendes låsen af ​​objektet. Sørg for, at outputtet er som vist nedenfor.

Output:

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

Forklaring af kode:

Når du kører denne kode, vil du bemærke, at den fungerer uden interferens, hvilket vi forventede. I den synkroniserede metode anvendes låsen af ​​metoden, men i den synkroniserede blokmetode anvendes låsen af ​​objektet.

Bruger statisk synkronisering

In Java synkronisering, hvis der er mere end et objekt, kan to tråde erhverve låsene og gå ind i en synkroniseret blok eller blok, med en separat lås for hvert objekt. For at undgå dette kan statisk synkronisering bruges. SyncHroniserede søgeord vil blive brugt før statiske metoder.

Bemærk: I statisk synkronisering er låseadgang på klassen, ikke objektet og metoden.

Kode til at demonstrere problemet med låsning af flere objekter

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();
    }
}

Forklaring af kode:

Når vi opretter en anden instans af `MathService`, introducerer vi interferens i trådene, da de vil blive sammenflettet med de to objekter. Bemærk, at tråd `0` og tråd `2` er sammenflettet med de to objekter, mens tråd `1` og `3` er sammenflettet med de to objekter.

Output:

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

Samme kode ved hjælp af synkroniseret statisk metode

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 ovenstående kode og bemærk, at vi nu har elimineret trådinterferens. Udgangen af ​​koden er vist nedenfor.

Output:

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

Fordele ved at bruge synkronisering

Her er fordelene ved at arbejde med samtidige applikationer:

  • Hovedformålet med synkronisering i Java er at forhindre inkonsistente data ved at forhindre trådinterferens.
  • Det synkroniserede søgeord i Java giver låsning, som sikrer gensidigt udelukkende adgang til den delte ressource og forhindrer dataræs.
  • Det forhindrer også omarrangering af kodesætninger af compiler, hvilket kan forårsage et subtilt samtidig problem, hvis vi ikke bruger flygtige eller synkroniserede søgeord.
  • Synchronized søgeord læser data fra hovedhukommelsen end cache, og når det frigiver låsen.
  • Det fjerner også skriveoperationer fra hovedhukommelsen, hvilket eliminerer hukommelsesinkonsistensfejl.

Ulemper ved Synchroniseringsmekanisme

Synchroniseringsmekanismer har dårlig ydeevne.

For eksempel

  • Antag, at der er fem processer, A1, A2, A3, A4 og A5.
  • De venter på, at de delte ressourcer får adgang til én tråd ad gangen.
  • Alle processer lades vente, så den sidste i køen skal vente til alle andre processer er færdige.

Resumé

  • Synchronisering refererer til evnen til at kontrollere adgangen af ​​flere tråde til enhver delt ressource.
  • Java har to typer synkroniseringsmetoder: 1) Processynkronisering og 2) Trådsynkronisering.
  • Fastlåse Java er bygget op omkring en intern enhed kendt som en skærm eller låsen.
  • Et flertrådet program er en metode eller blok, der er beskyttet mod interferens fra andre tråde, der deler den samme ressource angivet ved hjælp af nøgleordet "synkroniseret".
  • Enhver metode, der er erklæret som synkroniseret, er kendt som en synkroniseret metode.
  • In Java, tilgås synkroniserede metodelåse på metoden, hvorimod synkroniserede bloklåse tilgås på objektet.
  • I statisk synkronisering er låseadgang på klassen, ikke objektet og metoden.
  • Hovedformålet med synkronisering i Java er at forhindre inkonsistente data ved at forhindre trådinterferens.
  • Den største ulempe ved denne metode er, at alle processer holdes i vente, så den sidste i køen skal vente, indtil alle andre processer er færdige.