Java 未来对象的多并发问题

Java 未来对象的多并发问题,java,multithreading,concurrency,phaser,Java,Multithreading,Concurrency,Phaser,我正试图产生一些线程,并在执行时将它们放入一个列表中。当他们完成他们的处理,我想收集他们的结果介绍。这样我就可以有一个包含许多线程的列表,一旦它们可用,我就可以调用future.get并使用它们的回调信息 由于某种原因,我错过了很多结果。当我一步一步地浏览代码时,f.get在不应该被传递的时候被传递了,我不知道为什么 我的代码如下: public class ThreadTesterRunner { static List<Integer> rand

我正试图产生一些线程,并在执行时将它们放入一个列表中。当他们完成他们的处理,我想收集他们的结果介绍。这样我就可以有一个包含许多线程的列表,一旦它们可用,我就可以调用future.get并使用它们的回调信息

由于某种原因,我错过了很多结果。当我一步一步地浏览代码时,f.get在不应该被传递的时候被传递了,我不知道为什么

我的代码如下:

     public class ThreadTesterRunner {
            static List<Integer> randoms = new ArrayList<>();

            public static void main(String[] args) throws InterruptedException {
                final Phaser cb = new Phaser();
                ThreadRunner tr = new ThreadRunner(cb);
                Thread t = new Thread(tr, "Thread Runner");
                t.start();

                boolean process = true;
                // wait until all threads process, then print reports
                while (process){
                    if(tr.isFinished()){
                        System.out.println("Print metrics");
                        process = false;

                    }
                    Thread.sleep(1000);
                }
            }
        }


      class ThreadRunner implements Runnable {
            private ExecutorService executorService = Executors.newFixedThreadPool(10);
            private final Phaser barrier;
            private boolean finished=false;

            public ThreadRunner(Phaser phaser) {this.barrier = phaser;}

            public void run(){
                try {
                    List<Future<Integer>> list = new ArrayList<>();
                    boolean stillLoop = true; int i = 0;

                    final Phaser p = this.barrier;
                    Callable<Integer> task = new Callable<Integer>() {
                           public Integer call() throws Exception {
                               return new Reader().doRun(p);
                           }
                    };

                    List<Integer> randoms = new ArrayList<>();
                    Integer size;
                    while (stillLoop){
                        System.out.println("i "+i);
                        list.add(executorService.submit(task));

                        for(Future<Integer> f: list){
                            if(f.isDone()){
                                size = f.get();
                                System.out.println("size "+size);
                                list.remove(f);
                            } else {
                                  // keep processing
                            }
                        }
                        if(i == 2){
                            System.out.println("breaking out of loop");
                            stillLoop = false;
                        }
                        i++;
                    }
                    this.barrier.awaitAdvance(0);
                    this.finished=true;
                } catch (Exception e1) {
                    e1.printStackTrace();
                }
            }
            public boolean isFinished(){
                return this.finished;
            }
        }

class Reader {

    private Phaser readBarrier;
    private ExecutorService executorService = Executors.newFixedThreadPool(20);

    public Reader() {
    }    

    Random randomGenerator = new Random();

    public Integer doRun(Phaser phaser) throws Exception {
        phaser.register();
        this.readBarrier = phaser;
        System.out.println("Reading...");
        int i;

        int r = randomGenerator.nextInt(100);
        System.out.println("r "+r);
        ThreadTesterRunner.randoms.add(r);

        int a = this.readBarrier.arrive();
        return r; //i;
    }
}
你知道为什么会这样吗

编辑:

好的,我想我已经准备好了:

class ThreadRunner implements Runnable {
    // static int timeOutTime = 2;
    private ExecutorService executorService = Executors.newFixedThreadPool(10);
    private final Phaser barrier;
    private boolean finished = false;

    public ThreadRunner(Phaser phaser) {
        this.barrier = phaser;
    }

    public void run() {
        try {
            List<Future<Integer>> list = new CopyOnWriteArrayList<>(); 
            boolean stillLoop = true;
            int i = 0;

            final Phaser p = this.barrier;
            Callable<Integer> readerTask = new Callable<Integer>() {
                public Integer call() throws Exception {
                    return new Reader().doRun(p);
                }
            };

            List<Integer> randoms = new ArrayList<>();
            Integer size;
            while (stillLoop) {
                if (i <= 2) {
                    list.add(executorService.submit(readerTask));
                }

                if (!list.isEmpty()) {
                    for (Future<Integer> f : list) {
                        if (f.isDone()) {
                            size = f.get();
                            randoms.add(size);
                            System.out.println("Process read with a size of "+ size);
                            list.remove(f);
                        } else {
                            // System.out.println("skipping");
                        }
                    }
                } else {
                    stillLoop = false;
                }
                i++;
            }
            System.out.println("at barrier waiting");
            this.barrier.awaitAdvance(0);
            System.out.println("barrier crossed");
            this.finished = true;
        } catch (Exception e1) {
            e1.printStackTrace();
        }
    }

    public boolean isFinished() {
        return this.finished;
    }
}
结果: i 0 i 1 i 2 跳环 阅读 阅读 r 13 r 44 阅读 r 78 打印度量

我将ArrayList更改为向量,因为ArrayList不是线程安全的,这最终会导致ConcurrentModificationException


上面的输出是否符合您的预期?

我将列表更改为CopyOnWriteArrayList。我相信我已经知道发生了什么,并使其正常工作