JavaのLinkedBlockingQueueを使ってみる

f:id:dasshshsd:20200508193609p:plain
やりたいこと

import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;

public class Work {

    public static void main(String[] args) {
        final var queueSize = 1;
        final var queue = new LinkedBlockingQueue<String>(queueSize);
        final var isDone = new AtomicBoolean(false);
        final var es1 = Executors.newSingleThreadExecutor();
        final var es2 = Executors.newSingleThreadExecutor();

        final var w1 = CompletableFuture.runAsync(() -> {
            List.of("foo", "bar", "baz").forEach(str -> {
                try {
                    queue.put(str);
                    System.out.println("put \"" + str + '"');
                    Thread.sleep(3000);
                } catch (InterruptedException e) {
                    isDone.set(true);
                    throw new RuntimeException(e);
                }
            });
            isDone.set(true);
        }, es1);

        final var w2 = CompletableFuture.runAsync(() -> {
            while (!isDone.get() || !queue.isEmpty()) {
                try {
                    final var str = queue.poll(1, TimeUnit.SECONDS);
                    System.out.println(isDone.get());
                    if (str == null) {
                        continue;
                    }
                    System.out.println("take \"" + str + '"');
                } catch (InterruptedException e) {
                    w1.cancel(true);
                    throw new RuntimeException(e);
                }
            }
        }, es2);

        CompletableFuture.allOf(w1, w2).whenComplete((v, e) -> {
            es1.shutdown();
            es2.shutdown();
        }).join();
    }

}