简体   繁体   English

Java 8:ArrayDeque <>。poll在并行环境中返回null

[英]Java 8: ArrayDeque<>.poll returning null in parallel environment

I am trying to maintain a list of items among multiple threads, one for each thread (lets say one socket connection for each thread for example). 我试图维护多个线程中的项目列表,每个线程一个(例如,说每个线程一个套接字连接)。 I am maintaining this list in an ArrayDeque<> . 我在ArrayDeque<>维护此列表。 The problem I am facing is the ArrayDeque<> is exceeding the no of items more than no. 我面临的问题是ArrayDeque<>超过项目数超过了。 of threads in thread pool. 线程池中的线程数。

Here is my code: 这是我的代码:

package com.practice;

import java.util.ArrayDeque;
import java.util.Random;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

public class CompletableFutureApp implements AutoCloseable {
    private static void sleep(long timeMS) {
        try {
            Thread.sleep(timeMS);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        try (CompletableFutureApp completableFutureApp = new CompletableFutureApp()) {

            Runnable[] tasksList1 = new Runnable[100];

            for (int i = 0; i < tasksList1.length; i++) {
                String msg1 = "TaskList 1 no.: " + i;

                tasksList1[i] = () -> {
                    //System.out.println(msg1);
                    sleep(300);
                };
            }

            completableFutureApp
                    .executeTasks(tasksList1)
                    .thenRun(() -> System.out.println("All tasks completed successfully"));
        }
    }

    private ExecutorService threadPool = Executors.newWorkStealingPool(10);
    private ArrayDeque<Integer> itemsAvailable = new ArrayDeque<>();

    private CompletableFuture executeTasks(Runnable... tasks) {
        CompletableFuture[] futures = new CompletableFuture[tasks.length];

        for (int i = 0; i < tasks.length; i++) {
            Runnable task = tasks[i];

            futures[i] = CompletableFuture.runAsync(() -> {
                Integer item = itemsAvailable.poll();
                if (item == null)
                    item = new Random().nextInt();

                task.run();

                itemsAvailable.add(item);

                System.out.println("Items available: " + itemsAvailable.size());
            }, threadPool);
        }

        return CompletableFuture.allOf(futures).thenRun(() -> System.out.println("Items available at last: " + itemsAvailable.size()));
    }

    @Override
    public void close() {
        threadPool.shutdown();
        try {
            threadPool.awaitTermination(100, TimeUnit.SECONDS);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

As in my code, I am creating a work stealing pool of size 10 , Could anyone please let me know why no. 就像在我的代码中一样,我正在创建一个大小为10工作窃取池 ,有人可以让我知道为什么不这样做。 of elements in ArrayDeque<> is exceeding 10 in this case? 在这种情况下ArrayDeque<>的元素数超过10?

From the Javadoc : 从Javadoc

[Array deques] are not thread-safe; [数组双端队列]不是线程安全的; in the absence of external synchronization, they do not support concurrent access by multiple threads. 在没有外部同步的情况下,它们不支持多个线程的并发访问。

Use external synchronization, or select a different class which is specifically designed for concurrent access. 使用外部同步,或选择专门用于并发访问的其他类。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM