Javaでの同期に関する包括的なガイド
公開: 2022-05-20Javaでの同期について説明する前に、マルチスレッドの概念を簡単に再検討する必要があります。 Javaのマルチスレッド機能により、プログラムの2つ以上の部分を同時に実行して、CPUを最大限に活用できます。 このようなプログラムの各部分はスレッドであり、スレッドはプロセス内の軽量プロセスです。
現在、プログラムの複数のスレッドが同じリソースにアクセスしようとして、不正確な結果を生成する可能性があります。 したがって、特定の時点で1つのスレッドのみがリソースにアクセスできるようにするには、同期が必要です。
Javaでの同期とは何かに関するこのガイドでは、同期の概念について例を挙げて詳しく説明します。
Javaの同期とは何ですか?
Java同期は、共有リソースへの複数のスレッドのアクセスを制御する機能です。 マルチスレッドのJavaプログラムが同じリソースにアクセスしようとして、誤った結果を生成する場合に役立ちます。 Java同期機能を使用すると、特定の時点でリソースに到達できるのは1つのスレッドのみです。
Javaは、同じオブジェクト上で同期する同期ブロックを使用してスレッドのタスクを同期する方法を提供し、一度に1つのスレッドのみをスレッド内で実行できます。 これらのブロックは、synchronizedキーワードでマークされ、すでにブロック内にあるスレッドが実行を終了してブロックを離れるまで、同期ブロックに入ろうとする他のスレッドをブロックします。
同期ブロックを書き込むための構文
Javaで同期ブロックを作成するための一般的な構文は次のとおりです。
同期(lockObject)
{{
//同期されたステートメント
}
上記の構文では、 lockObjectは、ロックが同期された要素に関連しているオブジェクトを指します。 これで、Javaのロックの概念にたどり着きました。
Javaでのロック
Javaでの同期は、ロックまたはモニターを中心に構築されています。 すべてのオブジェクトにはロックが関連付けられています。 理想的には、オブジェクトのフィールドへのアクセスを必要とするスレッドは、最初にオブジェクトのロックを取得する必要があります。 ロックは、同期ブロックよりも洗練された柔軟なスレッド同期メカニズムです。 これは、広範なロック実装を含むjava.util.concurrent.lockパッケージ内で定義されています。
世界のトップ大学からオンラインソフトウェア開発コースを学びましょう。 エグゼクティブPGプログラム、高度な証明書プログラム、または修士プログラムを取得して、キャリアを迅速に追跡します。
Java同期メソッド
Java同期メソッドの目的は、共有リソースのオブジェクトをロックすることです。 したがって、スレッドが同期メソッドを呼び出すと、メソッドはそのオブジェクトのロックを自動的に取得し、スレッドがジョブを実行するとそれを解放します。
Java同期メソッドの例を次に示します。
//Java同期メソッドの例
クラステーブル{
同期されたvoidprintTable(int n){//同期されたメソッド
for(int i = 1; i <= 5; i ++){
System.out.println(n * i);
試す{
Thread.sleep(400);
} catch(Exception e){System.out.println(e);}
}
}
}
クラスMyThread1はThread{を拡張します
タブレット;
MyThread1(テーブルt){
this.t = t;
}
public void run(){
t.printTable(5);
}
}
クラスMyThread2はThread{を拡張します
タブレット;
MyThread2(テーブルt){
this.t = t;
}
public void run(){
t.printTable(100);
}
}
パブリッククラスTestSynchronization2{
public static void main(String args []){
Table obj = new Table();//1つのオブジェクトのみ
MyThread1 t1 = new MyThread1(obj);
MyThread2 t2 = new MyThread2(obj);
t1.start();
t2.start();
}
}
出力:
5
10
15
20
25
100
200
300
400
500
同期しないとどうなりますか?
ここで、同期なしの前のプログラムを見てみましょう(synchronizedキーワードがないことに注意してください)。
クラステーブル{
void printTable(int n){//メソッドが同期されていません
for(int i = 1; i <= 5; i ++){
System.out.println(n * i);
試す{
Thread.sleep(400);
} catch(Exception e){System.out.println(e);}
}
}
}
クラスMyThread1はThread{を拡張します
タブレット;
MyThread1(テーブルt){
this.t = t;
}
public void run(){
t.printTable(5);
}
}
クラスMyThread2はThread{を拡張します
タブレット;
MyThread2(テーブルt){
this.t = t;
}
public void run(){
t.printTable(100);
}
}
クラスTestSynchronization1{
public static void main(String args []){
Table obj = new Table();//1つのオブジェクトのみ
MyThread1 t1 = new MyThread1(obj);
MyThread2 t2 = new MyThread2(obj);
t1.start();
t2.start();
}
}
出力:
5
100
10
200
15
300
20
400
25
500
ご覧のとおり、同期がないと出力に一貫性がありません。
人気のソフトウェアエンジニアリングコースをご覧ください
SL。 いいえ | ソフトウェア開発プログラム | |
1 | LJMU&IIITBのコンピュータサイエンスの理学修士 | CaltechCTMEサイバーセキュリティ証明書プログラム |
2 | フルスタック開発ブートキャンプ | ブロックチェーンのPGプログラム |
3 | ソフトウェア開発のエグゼクティブ大学院プログラム-DevOpsの専門分野 | すべてのソフトウェアエンジニアリングコースを表示 |
Javaでの同期の種類
Javaでのスレッド同期とは何かに答えるために、スレッド同期とプロセス同期の2種類の同期を使用できます。
それぞれの意味を理解しましょう。
スレッドの同期:複数のスレッドが共有リソースにアクセスしようとする場合、リソースが一度に1つのスレッドのみによって使用されるようにする必要があります。 スレッドの同期は、複数のスレッドがリソースを同時に使用しようとしているときに、1つのスレッドのみが共有リソースを使用できるようにするプロセスです。
プロセスの同期:複数のプロセスを同時に実行して、プロセスが適切な実行順序にコミットする状態に到達することを指します。 2つ以上のプロセスが連携し、一方のプロセスの実行が他方に影響を与える場合、プロセスの同期が必要です。 したがって、プロセスの同期により、出力が不正確になる可能性が排除され、適切な実行順序が保証されます。
Javaでの同期方法
大まかに言って、Javaの同期には4つの方法があります。
- 同期された静的メソッド
- 同期されたインスタンスメソッド
- 静的メソッド内の同期ブロック
- インスタンスメソッド内の同期ブロック
Java同期の各メソッドをさらに詳しく見ていきましょう。
同期された静的メソッド
ここでは、synchronizedキーワードを使用して、Javaの静的メソッドをマークします。 Java同期静的メソッドの例を次に示します。
public static MyStaticCounter {
private static int count = 0;
パブリック静的同期ボイドインクリメント(整数値){
カウント+=値;
}
}
同期されたインスタンスメソッド
インスタンスメソッドで同期ブロックを使用する場合、各オブジェクトには同期メソッドがあります。 各オブジェクトは、メソッド内で実行できるスレッドを1つだけ持つことができます。 複数のオブジェクトがある場合、ブロック内のオブジェクトごとに1つのスレッドを実行できます。
パブリッククラスMyCounter{
private int count = 0;
パブリック同期ボイドインクリメント(整数値){
this.count+=値;
}
public synchronized void decrement(int value){
this.count-=値;
}
}
静的メソッド内の同期ブロック
以下は、静的メソッド内で同期ブロックを使用する例です。
パブリッククラスMyClass{
public static void print(String message){
同期(MyClass.class){
log.writeln(メッセージ);
}
}
}
インスタンスメソッド内の同期ブロック
メソッド全体を同期する代わりに、メソッド内の特定のブロックで同期を使用できます。 以下は、非同期メソッド内の同期されたコードブロックの例です。
public void incremental(int value){
同期(これ){
this.count+=値;
}
}
Javaでの同期の必要性
Javaでの同期とは何かがわかったので、そもそもなぜ同期を使用するのか疑問に思われるかもしれません。
Java同期キーワードは、並行プログラミングに不可欠な機能を提供します。 Javaでの同期がどのように役立つかを次に示します。
- Java同期は、スレッド間の競合状態を排除し、共有リソースへの相互に排他的なアクセスを保証するロック機能を提供します。
- Java同期ロックは、ロック機能とロック解除機能の両方を提供します。 したがって、スレッドは、同期されたメソッドまたはブロックに入る前にロックを取得する必要があります。
- synchronizedキーワードは、コンパイラーによるプログラム・ステートメントの並べ替えを防ぎます。
結論
要約すると、Javaでの同期により、一度に1つのスレッドのみが共有リソースにアクセスできるようになります。 Javaのsynchronizedキーワードを使用して、ブロックまたはメソッドを同期させることができます。 スレッドが同期されたブロック内に入りたい場合、ロックを取得する必要があり、ブロックを離れた後、スレッドはロックを解放します。 同期キーワードは、メソッドと一緒に使用することも、メソッドのブロック内で使用することもできます。
Javaをどこで学ぶべきか疑問に思っていますか?
ソフトウェアエンジニアリングにおけるupGradのジョブリンクPG認定 あなたが探しているものです!
新卒者と最終学年のために特別に設計された、ソフトウェアエンジニアリングにおけるupGradのジョブリンクPG認定は、プログラミングを学び、エントリーレベルのソフトウェアの役割に就きたい人に最適です。 この5か月のオンラインプログラムでは、Java、JavaScript、HTML5、DSA、AWS、MERNなどの最高のソフトウェアスキルを学びます。
Q:Javaで同期を使用するのはなぜですか?
A:Javaのsynchronizedキーワードにより、一度に1つのスレッドのみが共有リソースにアクセスできるようになります。 マルチスレッドのJavaプログラムが同じリソースにアクセスして、不正確な結果を生成しようとする場合に役立ちます。
Q:同期はJavaでどのように実装されますか?
A:Javaは、モニターの概念を使用して同期を実装します。モニターは、一度に1つのスレッドのみがモニターを所有します。 スレッドがロックを取得すると、モニターにアクセスし、ロックされたモニターに入ろうとする他のすべてのスレッドは、最初のスレッドがモニターを離れるまでブロックされたままになります。
Q:Javaのデッドロックとは何ですか?
A:Javaデッドロックは、スレッドがオブジェクトロックを待機しているときに発生しますが、別のスレッドがそれを取得し、2番目のスレッドが最初のスレッドによって取得されたオブジェクトロックを待機しています。 したがって、両方のスレッドが互いにロックを解放するのを待ち、デッドロックが発生します。