Javaでマルチスレッドの共有キューを実装の方法

Javaでは、java.util.concurrentパッケージ内のBlockingQueueを用いて、マルチスレッド共有キューを実装可能。

BlockingQueueはスレッドセーフなキューです。

  1. put(E e):要素をキューの末尾に追加し、キューが埋まっている場合はブロックして待機します。
  2. キュー先頭の要素を取り出して返します。キューが空の場合はブロックして待ちます。
  3. offer(E e): 要素をキューの末尾に追加する。キューがいっぱいの場合、false を返す。
  4. 先頭の要素を削除し、返します。キューが空の場合は null を返します。

以下に簡単なコードのサンプルを示します:

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;

public class SharedQueueExample {
    public static void main(String[] args) {
        // 创建一个容量为10的阻塞队列
        BlockingQueue<Integer> queue = new LinkedBlockingQueue<>(10);

        // 创建并启动多个生产者线程
        for (int i = 0; i < 5; i++) {
            new Producer(queue).start();
        }

        // 创建并启动一个消费者线程
        new Consumer(queue).start();
    }

    static class Producer extends Thread {
        private final BlockingQueue<Integer> queue;

        public Producer(BlockingQueue<Integer> queue) {
            this.queue = queue;
        }

        @Override
        public void run() {
            try {
                for (int i = 0; i < 10; i++) {
                    queue.put(i); // 阻塞等待直到队列有空闲位置
                    System.out.println("Produced: " + i);
                    Thread.sleep(1000);
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    static class Consumer extends Thread {
        private final BlockingQueue<Integer> queue;

        public Consumer(BlockingQueue<Integer> queue) {
            this.queue = queue;
        }

        @Override
        public void run() {
            try {
                while (true) {
                    int value = queue.take(); // 阻塞等待直到队列有可用元素
                    System.out.println("Consumed: " + value);
                    Thread.sleep(2000);
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

上のサンプルでは、10容量のブロッキングキューqueueを作成して、5個のプロデューサースレッドと1個のコンシューマスレッドを作成します。各プロデューサースレッドは、絶えずキューに要素を追加し、コンシューマスレッドは絶えずキューから要素を取り出して処理を行います。

BlockingQueueを利用することで、スレッド同期やWait/Notifyメカニズムを手動で実装する必要がなくなり、マルチスレッドプログラミングの複雑さが軽減されます。

bannerAds