効率的な並行アプリケーションを実現する鍵技術 Java 並行プログラミングを詳しく解説

序章:

現在のコンピューティングの世界では、効率的な同時プログラミングが Java 開発者にとってますます重要になっています。人気のあるプログラミング言語として、Java は同時プログラミングの強力なサポートを提供し、開発者がマルチコア プロセッサとスレッドの可能性を最大限に活用して、高性能、高スループットのアプリケーションを構築できるようにします。この記事では、スレッド セーフ、ロック、同時コレクション、アトミック操作、同時ツールなど、Java 同時プログラミングの主要なテクノロジを詳しく掘り下げ、詳細なコード例と説明を提供します。

1. スレッドの安全性

マルチスレッド環境では、スレッド セーフが効率的な同時プログラミングの基礎となります。スレッド セーフとは、複数のスレッドが共有リソースに同時にアクセスするときに、データの破損や不正な結果が発生しないという事実を指します。スレッド セーフを実現する一般的な方法は次のとおりです。

  • synchronized キーワード synchronized キーワードを使用すると、メソッドまたはコード ブロックを変更して、変更されたコード セグメントを同時に 1 つのスレッドだけが実行できるようにすることができます。相互排他ロック メカニズムを使用して、複数のスレッドが共有リソースに同時にアクセスする問題を回避します。サンプルコードは次のとおりです。
public class Counter {
    private int count = 0;

    public synchronized void increment() {
        count++; 
    }

    public synchronized int getCount() {
        return count;
    }
}
  • ReentrantLock ロック ReentrantLock は Java が提供するリエントラントなロックであり、synchronized に比べてより柔軟なロック機構を提供します。リエントラント ロックを使用すると、同じスレッドが同じロックを複数回取得できるようになり、デッドロックが回避されます。サンプルコードは次のとおりです。
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class Counter {
    private int count = 0;
    private Lock lock = new ReentrantLock();

    public void increment() {
        lock.lock();
        try {
            count++;
        } finally {
            lock.unlock();
        }
    }

    public int getCount() {
        lock.lock();
        try {
            return count;
        } finally {
            lock.unlock();
        }
    }
}

2、同時収集

Java は、マルチスレッド環境でのデータの安全なアクセスと操作のために、同時実行性が安全なさまざまなコレクション クラスを提供します。一般的に使用されるいくつかの同時コレクションを次に示します。

  • ConcurrentHashMap ConcurrentHashMap は、高度な同時読み取りおよび書き込み操作をサポートできる効率的な同時ハッシュ テーブル実装です。セグメント ロック メカニズムを使用し、異なるスレッドが異なるセグメント上で同時に動作できるため、同時実行パフォーマンスが向上します。サンプルコードは次のとおりです。
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

public class MyCache {
    private Map<String, Integer> cache = new ConcurrentHashMap<>();

    public void put(String key, int value) {
        cache.put(key, value);
    }

    public int get(String key) {
        return cache.getOrDefault(key, 0);
    }
}
  • CopyOnWriteArrayList CopyOnWriteArrayList は同時実行安全なリストの実装であり、読み取りが多く書き込みが少ないシナリオに適しています。ロックフリーの読み取り操作を実現し、書き込み操作中に新しいコピーを作成することで読み取りと書き込みの競合を回避します。サンプルコードは次のとおりです。
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;

public class MyList {
    private List<Integer> list = new CopyOnWriteArrayList<>();

    public void add(int value) {
        list.add(value);
    }

    public int get(int index) {
        return list.get(index);
    }
}

3. アトミック操作

アトミック操作とは、中断できない単一の操作を指し、すべてが成功するか、すべてが失敗してロールバックされます。Java は、スレッドセーフなアトミック操作を実装するためのさまざまなアトミック クラスを提供します。一般的に使用されるいくつかのアトミック クラスを次に示します。

  • AtomicBoolean AtomicBoolean は、アトミックな読み取りおよび変更操作を実現できるブール型のアトミック クラスです。内部では CAS (比較およびスワップ) アルゴリズムを使用して、操作のアトミック性を保証します。サンプルコードは次のとおりです。
import java.util.concurrent.atomic.AtomicBoolean;

public class MyFlag {
    private AtomicBoolean flag = new AtomicBoolean(false);

    public boolean getFlag() {
        return flag.get();
    }

    public void setFlag(boolean newValue) {
        flag.set(newValue);
    }
}
  • AtomicInteger AtomicInteger は、アトミックな自己インクリメントおよび自己デクリメント操作を実現できる整数型のアトミック クラスです。また、CAS アルゴリズムを使用して操作のアトミック性を保証します。サンプルコードは次のとおりです。
import java.util.concurrent.atomic.AtomicInteger;

public class Counter {
    private AtomicInteger count = new AtomicInteger(0);

    public void increment() {
        count.incrementAndGet();
    }

    public int getCount() {
        return count.get();
    }
}

4. 同時実行ツール

前述のスレッド セーフ、ロック、同時コレクション、およびアトミック操作に加えて、Java は、開発者が効率的な同時プログラミングをより適切に達成できるようにするいくつかの強力な同時実行ツールも提供します。

CountDownLatch CountDownLatch は、1 つ以上のスレッドが他のスレッドの操作が完了するまで待機できるようにする同期ツール クラスです。カウンタ メカニズムを使用し、カウンタが 0 になると、待機中のスレッドが起動されます。
サンプルコードは次のとおりです

public class MyTask は Runnable { private CountDownLatch ラッチを実装します。

public MyTask(CountDownLatch latch) {
    this.latch = latch;
}

@Override
public void run() {
    // 执行任务
    latch.countDown(); // 任务完成后计数减一
}

}

  • CyclicBarrier CyclicBarrier は、すべてのスレッドが特定のバリア ポイントに到達するまで、スレッドのグループが相互に待機できるようにする同期ツール クラスでもあります。CountDownLatch とは異なり、CyclicBarrier のカウンターはリセットして再利用できます。サンプルコードは次のとおりです。
import java.util.concurrent.CyclicBarrier;

public class MyTask implements Runnable {
    private CyclicBarrier barrier;

    public MyTask(CyclicBarrier barrier) {
        this.barrier = barrier;
    }

    @Override
    public void run() {
        // 执行任务
        barrier.await(); // 等待其他线程到达屏障点
    }
}

結論は:

この記事では、スレッド セーフ、ロック、同時コレクション、アトミック操作、同時ツールなどを含む Java 同時プログラミングの主要なテクノロジを詳細に紹介し、対応するコード例を示します。これらのテクノロジーを理解して習得することは、開発者が効率的で安定した同時実行アプリケーションを作成し、システムのパフォーマンスとスケーラビリティを向上させるのに役立ちます。これらのテクニックを徹底的に学び実践することで、開発者は同時プログラミング能力を向上させ、より信頼性が高く効率的なアプリケーションを構築できます。同時に、読者には、実際の開発プロセス中の特定のニーズに応じて適切なテクノロジとツールを選択し、アプリケーションの安定性とパフォーマンスを確保するために高品質の同時コードを記述することに注意することをお勧めします。

おすすめ

転載: blog.csdn.net/qq_54796785/article/details/131340784