Sync慢性化 Java

何ですか Sync慢性化 Java?

In Java同期とは、複数のスレッドによる共有リソースへのアクセスを制御する機能を指します。これは、共有リソースへのアクセスを 1 つのスレッドのみに許可する場合に最適なオプションです。

この実行方法は、通常、「非同期」プログラミングと呼ばれます。これらのプロセッサには、命令を同時に実行できる軽量プロセスであるスレッドもあります。

の種類 Sync神化

同期方法には2種類あります。 Java:

1) プロセス同期

2) スレッドの同期。

スレッドを勉強しましょう プロセス同期 詳細に。

プロセス同期: プログラム間の同期を管理します。たとえば、`Microsoft Word` および `Acrobat Reader` は個別のプロセスとして実行されます。

スレッド同期: 2 つ以上のスレッドによるクリティカル リソースの同時実行は、スレッドと呼ばれます。 Sync時代化。さらに、相互排他的な通信やスレッド間通信にグループ化することもできます。

ロックインとは何か Java?

固定する Java は、モニターまたはロックと呼ばれる内部エンティティを中心に構築されています。すべてのオブジェクトには、ロックが関連付けられています。したがって、オブジェクトのフィールドに一貫してアクセスする必要があるスレッドは、アクセスする前にオブジェクトのロックを取得し、作業が完了したらロックを解放する必要があります。これにより、一度に 1 つのスレッドだけが共有データにアクセスできるようになります。

同期機能を備えたマルチスレッドプログラム

マルチスレッドプログラム `synchronized` キーワードを使用して指定された同じリソースを共有する他のスレッドからの干渉から保護されたメソッドまたはブロックです。

同期方式の使用

同期化として宣言されたメソッドは、同期化メソッドと呼ばれます。また、共有リソースのオブジェクトをロックするためにも使用されます。つまり、スレッドが同期化メソッドを呼び出すと、そのオブジェクトのロックが自動的に取得され、タスクが完了するとロックが解放されます。

注意: synchronized キーワードはクラスや変数では使用できません。このキーワードで使用できるのはメソッドとブロックのみです。

なぜ使用 Sync古典的なメソッド?

  • これは、共有リソースのオブジェクトをロックするために使用されます。
  • synchronized メソッドが呼び出されるたびに、オブジェクトはロックを取得します。
  • ロックは、スレッドがその機能を完了するまで解放されません。

構文:

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

コードの説明:

この例を実行すると、スレッド `0` が最初に `mathService` オブジェクトのロックを取得し、実行が完了するまでこのロックを排他的に使用することがわかります。 このコードでは、スレッド `0` と `1` がインターリーブされていません。 出力は以下のようになります。

出力:

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

同期ブロックの使用

メソッド全体を同期したくないと仮定しましょう。代わりに、数行のコードを同期したいとします。その場合、 Synchronizedブロックは選択された同期に役立ちました Java コー​​ド。 Sync同期メソッド ロックはメソッドでアクセスされますが、同期ブロック ロックはオブジェクトでアクセスされます。

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

コードの説明:

このコードを実行すると、何の干渉もなく動作することがわかります。同期メソッドでは、メソッドによってロックが適用されますが、同期ブロックでは、オブジェクトによってロックが適用されます。出力が以下のようになっていることを確認します。

出力:

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

コードの説明:

このコードを実行すると、予想通り、干渉なく動作することがわかります。同期メソッドでは、メソッドによってロックが適用されますが、同期ブロック メソッドでは、オブジェクトによってロックが適用されます。

静的同期の使用

In Java 同期では、オブジェクトが複数ある場合、2 つのスレッドがロックを取得し、同期ブロックまたはブロックに入り、オブジェクトごとに個別のロックを取得することがあります。これを回避するには、静的同期を使用できます。 Synchronized キーワードは静的メソッドの前に使用されます。

注意: 静的同期では、ロック アクセスはオブジェクトやメソッドではなくクラスに対して行われます。

複数のオブジェクトのロックの問題を示すコード

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

コードの説明:

「MathService」の別のインスタンスを作成すると、スレッドが 0 つのオブジェクトとインターリーブされるため、スレッドに干渉が生じます。 スレッド「2」とスレッド「1」は 3 つのオブジェクトでインターリーブされ、スレッド「XNUMX」と「XNUMX」は XNUMX つのオブジェクトでインターリーブされることに注意してください。

出力:

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

同期された静的メソッドを使用した同じコード

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

上記のコードを実行すると、スレッドの干渉が排除されたことがわかります。 コードの出力を以下に示します。

出力:

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

同期を使用する利点

同時アプリケーションを使用する場合の利点は次のとおりです。

  • 同期の主な目的は Java スレッドの干渉を防ぐことでデータの不整合を防ぐことです。
  • synchronizedキーワードは Java ロックを提供し、共有リソースへの相互排他アクセスを保証し、データの競合を防ぎます。
  • また、コードステートメントの並べ替えも防止します。 コンパイラ、 volatile または synchronized キーワードを使用しない場合、微妙な同時実行の問題が発生する可能性があります。
  • Synchronized キーワードは、ロックを解放するときに、キャッシュではなくメイン メモリからデータを読み取ります。
  • また、メインメモリから書き込み操作をフラッシュし、メモリの不整合エラーを排除します。

の短所 Sync王権化の仕組み

Synchonization メカニズムのパフォーマンスが低い。

例えば、

  • A1、A2、A3、A4、A5 の XNUMX つのプロセスがあるとします。
  • 共有リソースが一度に XNUMX つのスレッドにアクセスするのを待っています。
  • すべてのプロセスは待機し続けるため、キューの最後のプロセスは、他のすべてのプロセスが完了するまで待機する必要があります。

製品概要

  • Synchronization は、任意の共有リソースへの複数のスレッドのアクセスを制御する機能を指します。
  • Java 同期方法には 2 種類あります。 1) プロセス同期と 2) スレッドの同期。
  • 固定する Java モニターまたはロックと呼ばれる内部エンティティを中心に構築されます。
  • マルチスレッド プログラムは、`synchronized` キーワードを使用して指定された同じリソースを共有する他のスレッドからの干渉から保護されたメソッドまたはブロックです。
  • 同期済みとして宣言されたメソッドはすべて同期メソッドと呼ばれます。
  • In Java同期メソッド ロックはメソッドでアクセスされますが、同期ブロック ロックはオブジェクトでアクセスされます。
  • 静的同期では、ロック アクセスはオブジェクトやメソッドではなくクラスに対して行われます。
  • 同期の主な目的は Java スレッドの干渉を防ぐことでデータの不整合を防ぐことです。
  • この方法の最大の欠点は、すべてのプロセスが待機状態になるため、キューの最後のプロセスは他のすべてのプロセスが完了するまで待たなければならないことです。