logo

Java での同期

Java の同期は、任意の共有リソースへの複数のスレッドのアクセスを制御する機能です。

1 つのスレッドのみに共有リソースへのアクセスを許可したい場合は、Java 同期の方が良いオプションです。

同期を使用する理由

同期は主に次の目的で使用されます。

  1. 糸の干渉を防ぎます。
  2. 一貫性の問題を防ぐため。

同期の種類

同期には 2 種類あります

  1. プロセスの同期
  2. スレッドの同期

ここでは、スレッドの同期についてのみ説明します。

スレッドの同期

スレッド同期には相互排他とスレッド間通信の 2 種類があります。

  1. 相互排他的
    1. 同期メソッド。
    2. 同期ブロック。
    3. 静的同期。
  2. 連携(Javaにおけるスレッド間通信)

相互排他的

相互排他的機能は、データ共有中にスレッドが相互に干渉するのを防ぐのに役立ちます。これは、次の 3 つの方法を使用して実現できます。

  1. 同期方式を使用する場合
  2. 同期ブロックを使用する場合
  3. 静的同期を使用する場合

Java におけるロックの概念

同期は、ロックまたはモニターとして知られる内部エンティティを中心に構築されます。すべてのオブジェクトにはロックが関連付けられています。慣例により、オブジェクトのフィールドに一貫してアクセスする必要があるスレッドは、オブジェクトにアクセスする前にオブジェクトのロックを取得し、フィールドへのアクセスが完了したらロックを解放する必要があります。

Java 5 以降、パッケージ java.util.concurrent.locks にはいくつかのロック実装が含まれています。

同期なしの問題を理解する

この例では同期がないため、出力に一貫性がありません。例を見てみましょう:

TestSynchronization1.java

 class Table{ void printTable(int n){//method not synchronized for(int i=1;i<=5;i++){ system.out.println(n*i); try{ thread.sleep(400); }catch(exception e){system.out.println(e);} } class mythread1 extends thread{ table t; mythread1(table t){ this.t="t;" public void run(){ t.printtable(5); mythread2 mythread2(table t.printtable(100); testsynchronization1{ static main(string args[]){ obj="new" table(); only one object t1="new" mythread1(obj); t2="new" mythread2(obj); t1.start(); t2.start(); < pre> <p> <strong>Output:</strong> </p> <pre> 5 100 10 200 15 300 20 400 25 500 </pre> <h3>Java Synchronized Method</h3> <p>If you declare any method as synchronized, it is known as synchronized method.</p> <p>Synchronized method is used to lock an object for any shared resource.</p> <p>When a thread invokes a synchronized method, it automatically acquires the lock for that object and releases it when the thread completes its task.</p> <p> <strong>TestSynchronization2.java</strong> </p> <pre> //example of java synchronized method class Table{ synchronized void printTable(int n){//synchronized method for(int i=1;i<=5;i++){ system.out.println(n*i); try{ thread.sleep(400); }catch(exception e){system.out.println(e);} } class mythread1 extends thread{ table t; mythread1(table t){ this.t="t;" public void run(){ t.printtable(5); mythread2 mythread2(table t.printtable(100); testsynchronization2{ static main(string args[]){ obj="new" table(); only one object t1="new" mythread1(obj); t2="new" mythread2(obj); t1.start(); t2.start(); < pre> <p> <strong>Output:</strong> </p> <pre> 5 10 15 20 25 100 200 300 400 500 </pre> <h3>Example of synchronized method by using annonymous class</h3> <p>In this program, we have created the two threads by using the anonymous class, so less coding is required.</p> <p> <strong>TestSynchronization3.java</strong> </p> <pre> //Program of synchronized method by using annonymous class class Table{ synchronized void printTable(int n){//synchronized method for(int i=1;i<=5;i++){ system.out.println(n*i); try{ thread.sleep(400); }catch(exception e){system.out.println(e);} } public class testsynchronization3{ static void main(string args[]){ final table obj="new" table(); only one object thread t1="new" thread(){ run(){ obj.printtable(5); }; t2="new" obj.printtable(100); t1.start(); t2.start(); < pre> <p> <strong>Output:</strong> </p> <pre> 5 10 15 20 25 100 200 300 400 500 </pre> <hr></=5;i++){></pre></=5;i++){></pre></=5;i++){>

Java同期メソッド

メソッドを同期済みとして宣言した場合、そのメソッドは同期メソッドと呼ばれます。

同期メソッドは、共有リソースのオブジェクトをロックするために使用されます。

スレッドが同期メソッドを呼び出すと、そのオブジェクトのロックが自動的に取得され、スレッドがタスクを完了するとロックが解放されます。

TestSynchronization2.java

 //example of java synchronized method class Table{ synchronized void printTable(int n){//synchronized method for(int i=1;i<=5;i++){ system.out.println(n*i); try{ thread.sleep(400); }catch(exception e){system.out.println(e);} } class mythread1 extends thread{ table t; mythread1(table t){ this.t="t;" public void run(){ t.printtable(5); mythread2 mythread2(table t.printtable(100); testsynchronization2{ static main(string args[]){ obj="new" table(); only one object t1="new" mythread1(obj); t2="new" mythread2(obj); t1.start(); t2.start(); < pre> <p> <strong>Output:</strong> </p> <pre> 5 10 15 20 25 100 200 300 400 500 </pre> <h3>Example of synchronized method by using annonymous class</h3> <p>In this program, we have created the two threads by using the anonymous class, so less coding is required.</p> <p> <strong>TestSynchronization3.java</strong> </p> <pre> //Program of synchronized method by using annonymous class class Table{ synchronized void printTable(int n){//synchronized method for(int i=1;i<=5;i++){ system.out.println(n*i); try{ thread.sleep(400); }catch(exception e){system.out.println(e);} } public class testsynchronization3{ static void main(string args[]){ final table obj="new" table(); only one object thread t1="new" thread(){ run(){ obj.printtable(5); }; t2="new" obj.printtable(100); t1.start(); t2.start(); < pre> <p> <strong>Output:</strong> </p> <pre> 5 10 15 20 25 100 200 300 400 500 </pre> <hr></=5;i++){></pre></=5;i++){>

匿名クラスを利用した同期方法の例

このプログラムでは、匿名クラスを使用して 2 つのスレッドを作成したため、必要なコーディングは少なくなります。

TestSynchronization3.java

 //Program of synchronized method by using annonymous class class Table{ synchronized void printTable(int n){//synchronized method for(int i=1;i<=5;i++){ system.out.println(n*i); try{ thread.sleep(400); }catch(exception e){system.out.println(e);} } public class testsynchronization3{ static void main(string args[]){ final table obj="new" table(); only one object thread t1="new" thread(){ run(){ obj.printtable(5); }; t2="new" obj.printtable(100); t1.start(); t2.start(); < pre> <p> <strong>Output:</strong> </p> <pre> 5 10 15 20 25 100 200 300 400 500 </pre> <hr></=5;i++){>