ホームページ >Java >&#&チュートリアル >シンクロナイザーのコード例

シンクロナイザーのコード例

Barbara Streisand
Barbara Streisandオリジナル
2025-01-09 14:07:42805ブラウズ

Exemplos de código para os sincronizadores

項目 80 で説明したシンクロナイザーのコード例と、研究を容易にするための使用方法の説明を示します。

1. CountDownLatch: スレッド調整用の使い捨てバリア
CountDownLatch を使用すると、1 つ以上のスレッドが、他のスレッドによって実行された一連の操作が完了するまで待機できます。

import java.util.concurrent.CountDownLatch;

public class CountDownLatchExample {
    public static void main(String[] args) throws InterruptedException {
        int numberOfWorkers = 3;
        CountDownLatch latch = new CountDownLatch(numberOfWorkers);

        for (int i = 0; i < numberOfWorkers; i++) {
            new Thread(new Worker(latch, "Worker-" + i)).start();
        }

        System.out.println("Waiting for workers to finish...");
        latch.await(); // Aguarda todos os trabalhadores chamarem latch.countDown()
        System.out.println("All workers are done. Proceeding...");
    }

    static class Worker implements Runnable {
        private final CountDownLatch latch;
        private final String name;

        Worker(CountDownLatch latch, String name) {
            this.latch = latch;
            this.name = name;
        }

        @Override
        public void run() {
            System.out.println(name + " is working...");
            try {
                Thread.sleep((long) (Math.random() * 2000)); // Simula trabalho
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
            System.out.println(name + " finished.");
            latch.countDown(); // Decrementa o contador
        }
    }
}

2.セマフォ: 共有リソースへのアクセスを制御
セマフォは、限られたリソースへのアクセスを制御する一連の権限を管理します。

import java.util.concurrent.Semaphore;

public class SemaphoreExample {
    public static void main(String[] args) {
        int permits = 2; // Número de permissões disponíveis
        Semaphore semaphore = new Semaphore(permits);

        for (int i = 1; i <= 5; i++) {
            new Thread(new Task(semaphore, "Task-" + i)).start();
        }
    }

    static class Task implements Runnable {
        private final Semaphore semaphore;
        private final String name;

        Task(Semaphore semaphore, String name) {
            this.semaphore = semaphore;
            this.name = name;
        }

        @Override
        public void run() {
            try {
                System.out.println(name + " is waiting for a permit...");
                semaphore.acquire(); // Adquire uma permissão
                System.out.println(name + " got a permit and is working...");
                Thread.sleep((long) (Math.random() * 2000)); // Simula trabalho
                System.out.println(name + " is releasing a permit.");
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            } finally {
                semaphore.release(); // Libera a permissão
            }
        }
    }
}

3. CyclicBarrier: 再利用可能なバリア ポイントの同期
CyclicBarrier は、共通ポイント (バリア) で複数のスレッドを同期します。すべてのスレッドがバリア ポイントに到達した後、再利用できます。

import java.util.concurrent.CyclicBarrier;

public class CyclicBarrierExample {
    public static void main(String[] args) {
        int numberOfThreads = 3;
        CyclicBarrier barrier = new CyclicBarrier(numberOfThreads, () -> {
            System.out.println("All threads have reached the barrier. Proceeding...");
        });

        for (int i = 0; i < numberOfThreads; i++) {
            new Thread(new Task(barrier, "Thread-" + i)).start();
        }
    }

    static class Task implements Runnable {
        private final CyclicBarrier barrier;
        private final String name;

        Task(CyclicBarrier barrier, String name) {
            this.barrier = barrier;
            this.name = name;
        }

        @Override
        public void run() {
            try {
                System.out.println(name + " is performing some work...");
                Thread.sleep((long) (Math.random() * 2000)); // Simula trabalho
                System.out.println(name + " reached the barrier.");
                barrier.await(); // Aguarda todas as threads chegarem à barreira
                System.out.println(name + " passed the barrier.");
            } catch (Exception e) {
                Thread.currentThread().interrupt();
            }
        }
    }
}

4. Phaser: 高度で動的なスレッド同期
Phaser は CyclicBarrier に似ていますが、スレッドの動的出入りをサポートします。

import java.util.concurrent.Phaser;

public class PhaserExample {
    public static void main(String[] args) {
        Phaser phaser = new Phaser(1); // Registra o "partida principal"

        for (int i = 0; i < 3; i++) {
            new Thread(new Task(phaser, "Task-" + i)).start();
        }

        // Avança para a próxima fase após garantir que todas as threads registradas concluíram
        System.out.println("Main thread waiting for phase 1 completion...");
        phaser.arriveAndAwaitAdvance();

        System.out.println("All tasks completed phase 1. Main thread moving to phase 2...");
        phaser.arriveAndDeregister(); // Desregistra a thread principal
    }

    static class Task implements Runnable {
        private final Phaser phaser;
        private final String name;

        Task(Phaser phaser, String name) {
            this.phaser = phaser;
            this.name = name;
            phaser.register(); // Registra a thread no Phaser
        }

        @Override
        public void run() {
            System.out.println(name + " is working on phase 1...");
            try {
                Thread.sleep((long) (Math.random() * 2000)); // Simula trabalho
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
            System.out.println(name + " completed phase 1.");
            phaser.arriveAndAwaitAdvance(); // Indica chegada na fase atual e aguarda

            System.out.println(name + " is working on phase 2...");
            try {
                Thread.sleep((long) (Math.random() * 2000)); // Simula trabalho
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
            System.out.println(name + " completed phase 2.");
            phaser.arriveAndDeregister(); // Indica chegada e desregistra
        }
    }
}

これらの例は、各シンクロナイザーがどのように機能するかを理解するのに役立ちます。スレッドの数とタイミングを調整して実験し、同期動作への影響を観察できます。

以上がシンクロナイザーのコード例の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。