Java での同期ガイド
公開: 2022-10-23Java での同期について説明する前に、マルチスレッドの概念を簡単に再検討する必要があります。 Java のマルチスレッド機能により、プログラムの 2 つ以上の部分を同時に実行して、CPU 使用率を最大化できます。 このようなプログラムの各部分はスレッドであり、スレッドはプロセス内の軽量プロセスです。
現在、プログラムの複数のスレッドが同じリソースにアクセスしようとして、不正確な結果を生成する可能性があります。 そのため、特定の時点で 1 つのスレッドのみがリソースにアクセスできるようにするために、何らかの同期が必要です。
無料のテクノロジー コースをチェックして、競争で優位に立ちましょう。
Java での同期とは何かに関するこのガイドでは、例を使用して同期の概念を詳しく説明します。
世界トップクラスの大学が提供するソフトウェア開発コースをオンラインで学びましょう。 エグゼクティブ PG プログラム、上級認定プログラム、または修士プログラムを取得して、キャリアを加速させましょう。
Javaの同期とは何ですか?
Java 同期は、共有リソースへの複数のスレッドのアクセスを制御する機能です。 これは、マルチスレッドの Java プログラムが同じリソースにアクセスしようとして誤った結果を生成する場合に役立ちます。 Java 同期機能を使用すると、特定の時点で 1 つのスレッドのみがリソースにアクセスできます。
Java は、同じオブジェクトで同期する同期ブロックを使用してスレッドのタスクを同期する方法を提供し、一度に 1 つのスレッドのみを内部で実行できます。 これらのブロックは synchronized キーワードでマークされ、すでにブロック内にあるスレッドが実行を終了してブロックを離れるまで、同期ブロックに入ろうとする他のスレッドをブロックします。
DevOps における upGrad の Advanced Certification を確認してください
同期ブロックを書き込むための構文
Java で同期ブロックを記述するための一般的な構文は次のとおりです。
同期 (lockObject)
{
// 同期ステートメント
}
人気のソフトウェア エンジニアリング コースを探す
LJMU & IIITB のコンピューター サイエンスの理学修士号 | カリフォルニア工科大学 CTME サイバーセキュリティ証明書プログラム |
フルスタック開発ブートキャンプ | ブロックチェーンのPGプログラム |
フルスタック開発のエグゼクティブ PG プログラム | |
以下のすべてのコースを表示 | |
ソフトウェア工学コース |
上記の構文では、 lockObjectは、同期された要素に関連するロックを持つオブジェクトを参照します。 ここで、Java のロックの概念について説明します。
upGrad のサイバー セキュリティに関する Advanced Certification を確認してください
Java でのロック
Java での同期は、ロックまたはモニターを中心に構築されています。 すべてのオブジェクトには、ロックが関連付けられています。 理想的には、オブジェクトのフィールドへのアクセスを必要とするスレッドは、最初にオブジェクトのロックを取得する必要があります。 ロックは、同期ブロックよりも洗練された柔軟なスレッド同期メカニズムです。 これは、広範なロックの実装を含む java.util.concurrent.lock パッケージ内で定義されています。
需要の高いソフトウェア開発スキル
JavaScriptコース | コア Java コース | データ構造コース |
Node.js コース | SQLコース | フルスタック開発コース |
NFTコース | DevOps コース | ビッグデータコース |
React.js コース | サイバーセキュリティコース | クラウドコンピューティングコース |
データベース設計コース | パイソンコース | 暗号通貨コース |
Java 同期メソッド
Java 同期メソッドの目的は、共有リソースのオブジェクトをロックすることです。 したがって、スレッドが同期メソッドを呼び出すと、メソッドはそのオブジェクトのロックを自動的に取得し、スレッドがそのジョブを実行すると解放します。
Java 同期メソッドの例を次に示します。
//Java 同期メソッドの例
クラステーブル{
同期された 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);}
}
}
}
class MyThread1 extends Thread{
タブレット;
MyThread1(テーブル t){
this.t=t;
}
public void run(){
t.printTable(5);
}
}
class MyThread2 extends 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=新しい MyThread1(obj);
MyThread2 t2=新しい MyThread2(obj);
t1.start();
t2.start();
}
}
ソフトウェア開発に関連する人気記事を読む
Java でデータ抽象化を実装するには? | Javaの内部クラスとは何ですか? | Java 識別子: 定義、構文、および例 |
例を使用して OOPS のカプセル化を理解する | C のコマンド ライン引数の説明 | 2022 年のクラウド コンピューティングの機能と特性トップ 10 |
Java のポリモーフィズム: 概念、型、特徴、および例 | Java のパッケージとその使用方法 | 初心者向け Git チュートリアル: Git をゼロから学ぶ |
出力:
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);}
}
}
}
class MyThread1 extends Thread{
タブレット;
MyThread1(テーブル t){
this.t=t;
}
public void run(){
t.printTable(5);
}
}
class MyThread2 extends 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=新しい MyThread1(obj);
MyThread2 t2=新しい MyThread2(obj);
t1.start();
t2.start();
}
}
出力:
5
100
10
200
15
300
20
400
25
500
ご覧のとおり、同期しないと出力に一貫性がありません。
Java での同期の種類
Java でのスレッド同期とは何かに答えるために、スレッド同期とプロセス同期の 2 種類の同期を使用できます。
それぞれの意味を理解しましょう。
スレッドの同期:複数のスレッドが共有リソースにアクセスしようとする場合、リソースが一度に 1 つのスレッドだけによって使用されるようにする必要があります。 スレッド同期は、複数のスレッドがリソースを同時に使用しようとしているときに、1 つのスレッドのみが共有リソースを使用できるようにするプロセスです。
プロセスの同期:複数のプロセスが同時に実行され、プロセスが適切な順序で実行される状態になることを指します。 プロセスの同期は、2 つ以上のプロセスが連携し、一方のプロセスの実行が他方のプロセスに影響を与える場合に必要です。 したがって、プロセスの同期により、不正確な出力の可能性が排除され、適切な実行順序が保証されます。
Java での同期方法
Java には、大まかに次の 4 つの同期方法があります。
- 同期された静的メソッド
- 同期されたインスタンス メソッド
- 静的メソッド内の同期ブロック
- インスタンスメソッド内の同期ブロック
Java 同期の各方法を詳しく見てみましょう。
同期された静的メソッド
ここでは、synchronized キーワードを使用して、Java の静的メソッドをマークします。 Java 同期静的メソッドの例を次に示します。
パブリック静的MyStaticCounter {
プライベート静的 int カウント = 0;
public static synchronized void increment(int value) {
カウント += 値;
}
}
同期されたインスタンス メソッド
インスタンス メソッドで同期ブロックを使用する場合、各オブジェクトには同期メソッドがあります。 各オブジェクトは、メソッド内で実行できるスレッドを 1 つだけ持つことができます。 複数のオブジェクトがある場合、ブロック内のオブジェクトごとに 1 つのスレッドを実行できます。
パブリック クラス MyCounter {
プライベート int カウント = 0;
パブリック同期ボイドインクリメント(int値){
this.count += 値;
}
パブリック同期ボイドデクリメント(int値){
this.count -= 値;
}
}
静的メソッド内の同期ブロック
以下は、静的メソッド内で同期ブロックを使用する例です。
パブリック クラス MyClass {
public static void print(文字列メッセージ) {
同期された(MyClass.class) {
log.writeln(メッセージ);
}
}
}
インスタンスメソッド内の同期ブロック
メソッド全体を同期する代わりに、メソッド内の特定のブロックで同期を使用できます。 以下は、非同期メソッド内のコードの同期ブロックの例です。
パブリックボイドインクリメント(整数値){
同期(これ) {
this.count += 値;
}
}
Java での同期の必要性
Java での同期とは何かがわかったので、そもそもなぜ同期を使用するのか疑問に思うかもしれません。
Java synchronized キーワードは、並行プログラミングに不可欠な機能を提供します。 Java での同期がどのように役立つかを次に示します。
- Java 同期は、スレッド間の競合状態を排除し、共有リソースへの相互排他的アクセスを保証するロック機能を提供します。
- Java 同期ロックは、ロック機能とロック解除機能の両方を提供します。 したがって、スレッドは、同期されたメソッドまたはブロックに入る前にロックを取得する必要があります。
- synchronized キーワードは、コンパイラによるプログラム ステートメントの並べ替えを防ぎます。
結論
要約すると、Java での同期は、一度に 1 つのスレッドのみが共有リソースにアクセスできるようにします。 Java synchronized キーワードを使用して、ブロックまたはメソッドを同期化できます。 スレッドが同期ブロック内に入りたい場合は、ロックを取得する必要があり、ブロックを離れた後、スレッドはロックを解放します。 synchronized キーワードは、メソッドまたはメソッドのブロック内で使用できます。
Java の中心的な概念を学びたいですか? upGrad Executive Post Graduate Program in Software Development – Specialization in Full Stack Developmentコースは、ソフトウェア開発のキャリアを探求したい初心者向けの 7 週間のオンライン プログラムです。 ライブおよびインタラクティブなクラス、練習セッション、および業界のリーダーが提供する 35 時間以上のコンテンツに参加して、upGrad から修了証明書を取得してください。
今すぐサインアップして、24 時間年中無休の学生サポートと業界ネットワーキングの独占的なupGrad 特典を利用してください!
Javaで同期を使用するのはなぜですか?
Java の synchronized キーワードは、一度に 1 つのスレッドだけが共有リソースにアクセスできるようにします。 これは、マルチスレッド Java プログラムが同じリソースにアクセスして不正確な結果を生成しようとする場合に役立ちます。
同期はJavaでどのように実装されていますか?
Java は、モニターの概念を使用して同期を実装し、特定の時点でモニターを所有するスレッドは 1 つだけです。 スレッドがロックを取得すると、そのスレッドはモニターにアクセスできるようになり、ロックされたモニターに入ろうとする他のすべてのスレッドは、最初のスレッドがモニターを離れるまでブロックされたままになります。
Javaのデッドロックとは何ですか?
Java デッドロックは、スレッドがオブジェクト ロックを待機しているときに、別のスレッドがそれを取得し、2 番目のスレッドが最初のスレッドによって取得されたオブジェクト ロックを待機している場合に発生します。 したがって、両方のスレッドが互いのロックを解放するのを待つため、デッドロックが発生します。