閲覧中:
1.13.synchronized

1.13.synchronized

[200~Java の synchronized は、マルチスレッド環境において 「一度にひとつのスレッドしか特定のコードブロックやメソッド にアクセスできない」ように制御する(排他制御)ためのキーワ ードです。 ご指定通り、F5キーをプログラムの実行(Execution)のトリガー と想定した、実用的でバリエーション豊かな 10 個のサンプルを 紹介します。 1. インスタンスメソッドの同期 最も基本的な形式です。メソッド全体にロックをかけます。

Java
public class Counter {
    private int count = 0;
        // F5 で実行すると、安全にカウントアップされます
            public synchronized void increment() {
        count++;

            }

}

  1. インスタンス内でのコードブロック同期 メソッド全体ではなく、特定の処理だけを同期させることでパフ ォーマンスを向上させます。

    Java
    public void addData(String data) {
        // 準備処理などは非同期で実行可能
            synchronized(this) {
            this.list.add(data);
    
            }
    
    }
    

  2. スタティックメソッドの同期(クラスロック) インスタンスが別々でも、クラス単位で 1 つのスレッドしか実行 できないようにします。

    Java
    public class GlobalConfig {
        private static int value = 0;
            public static synchronized void update(int newValue)
            {
            value = newValue;
    
            }
    
    }
    

  3. 独自のロック用オブジェクトを使用 this をロックすると外部から意図せずロックされるリスクがある ため、専用のオブジェクトを用意します。

    Java
    public class SecureService {
        private final Object lock = new Object();
    
                public void perform() {
            synchronized(lock) {
                // 安全な処理
    
            }
    
                }
    
    }
    

  4. 読み取り/書き込みの整合性確保 値を取得する際も synchronized にすることで、書き込み中の不 完全なデータを読み取るのを防ぎます。 private int score; public synchronized void setScore(int s) { score = s; } public synchronized int getScore() { return score; }

  5. デッドロックの回避(順序制御) 2つのロックが必要な場合、常に同じ順番でロックを取得するよう に設計します。 public void transfer(Account a, Account b) { synchronized(lockA) { synchronized(lockB) { // AからBへ送金

    Text Only
    }
    

    }

}

  1. 再入可能(Reentrant)の確認 Java の synchronized は、既にロックを保持しているスレッドが 再度同じロックを取得できます。

    Java
    public synchronized void methodA() {
        methodB(); // 同じスレッドならデッドロックせず実行可能
    
    }
    public synchronized void methodB() {
        // 処理
    
    }
    

  2. コレクション操作の同期 ArrayList などの非スレッドセーフなリストを安全に操作します。

    Java
    private List<String> names = new ArrayList<>();
    public void addName(String name) {
        synchronized(names) {
            names.add(name);
    
        }
    
    }
    

  3. Singleton パターンでの Double-Checked Locking リソースを節約しつつ、スレッドセーフにインスタンスを生成し ます。

    Java
    public class Database {
        private static volatile Database instance;
            public static Database getInstance() {
            if (instance == null) {
                synchronized(Database.class) {
                    if (instance == null) instance = new
                    Database();
    
                }
    
            }
                    return instance;
    
            }
    
    }
    

  4. wait/notify との組み合わせ スレッド間の通信(待ち合わせ)に利用します。

Java
public synchronized void produce() throws
InterruptedException {
    while (isFull) wait(); // 空くまで待機
        // 生成処理...
            notifyAll(); // 他のスレッドへ通知

}

synchronized の仕組み | 種類 | ロック対象 | 影響範囲 | |----------------------|-------------------------|-------------------------------------| | インスタンスメソッド | this (そのインスタンス) | 同じイン スタンスを使う他スレッド | | スタティックメソッド | Class オブジェクト | 全インスタン スの全スレッド | | コードブロック | 指定した任意の Object | 指定オブジェクト を共有するスレッド |

これらのコードをエディタに貼り付け、F5 を押して挙動を確認し てみてください。特定のサンプルについて、より詳細な解説や完 全な実行コードが必要ですか? ]