【问题标题】:Running Runnable in CompletableFuture multiple time在 CompletableFuture 中多次运行 Runnable
【发布时间】:2018-08-16 14:46:09
【问题描述】:

我想执行多个线程,这些线程将尝试同时添加到我的自定义列表 MyList,但是当我尝试获取计数时我没有看到任何输出

    public static void main(String[] args) {

        MyList<String> list = new list<String>();

        MyRunner<String> myRunner = new MyRunner<String>(list);

        ExecutorService threadPool = Executors.newFixedThreadPool(4);

        for(int i = 0; i < 20; i++) {
            CompletableFuture.runAsync(new MyRunner<String>(list));
        }

        try {
            threadPool.awaitTermination(100l, TimeUnit.SECONDS);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println(list.getCount());
}

跑步者类:

class MyRunner<String> implements Runnable {

    MyList<String> list;

    public MyRunner(MyList <String> t) {
        this.list = t;
    }

    @Override
    public void run() {
        for(int i = 0; i < 200; i++) {
            list((String) (i + Thread.currentThread().getName()));
        }

    }
}

类我的列表:

public class MyList<T> {

    Queue<T> blockingQueue;
    Lock lock;

    long count;

    public MyList() {
        blockingQueue = new LinkedList<>();
        count = 0;
        lock = new ReentrantLock();
    }

    public void add(T singleTon) {
        lock.lock();
        blockingQueue.offer(singleTon);
        count +=1;
        lock.unlock();
    }

    public long getCount() {
        return count;
    }


}

跟进问题:

使用CountDownLatch 程序没有结束。 sysout 的数量是 10001,最后一个输出是 In runnable: 9 : pool-1-thread-1

CountDownLatch 实现:

public static void main(String[] args) throws InterruptedException {

        MyList<String> mylist = new MyList<>();

        CountDownLatch latch = new CountDownLatch(10);

        ExecutorService executorService = Executors.newFixedThreadPool(4);


        for(int i = 0; i < 1000; i++) {
            CompletableFuture.runAsync(new MyRunner<String>(mylist, latch), executorService);
        }

        latch.await();

        System.out.println(mylist.count);
    }


class MyRunner<String> implements Runnable {

    MyList<String> mylist;
    CountDownLatch latch;

    public MyRunner(MyList<String> mylist, CountDownLatch latch) {
       this.latch = latch;
       this.mylist = mylist;
    }

    @Override
    public void run() {
        for(int i = 0; i < 10; i++) {
            System.out.println("In runnable: "+ i + " : "+ Thread.currentThread().getName());
            mylist.add((String)("" + i));
        }

        latch.countDown();
    }
}

【问题讨论】:

  • 提示:你在使用那个线程池吗? IDE 会告诉你...
  • 请发帖minimal reproducible example。您发布的代码不仅无法编译,而且不包含重要信息,例如您的列表实现。
  • @assylias :已编辑问题。它现在还包括 CountDownLatch 实现。
  • Latch 有计数 10,你循环 1000 次。看到问题了吗?此外,您永远不会 shutdown ExecutorService 并且您的线程不是守护进程,因此程序永远不会完成。
  • 就是这样!如果倒计时少于 Runnables 的数量,可能是关于 CountDownLatch 行为的后续问题(或将在新线程中发布)

标签: java concurrency java-8 java.util.concurrent


【解决方案1】:

您调用的CompletableFuture.runAsync(Runnable runnable) 不使用您创建的Executor。 通过传递您的 Executor 实例来代替 CompletableFuture.runAsync(Runnable runnable, Executor executor),例如:

CompletableFuture.runAsync(new MyRunner<String>(list), threadPool);

【讨论】:

  • 太棒了!谢谢。看来我还没等到结果出来。
  • 跟进:是否有一些关于正确等待所有线程完成的最佳实践?
  • @NoviceUser CountDownLatch 很可能是您需要查看的内容
  • @Eugene :我试了一下(问题编辑为CountDownLatch implementation),但程序没有终止。有什么想法吗?
  • @NoviceUser 您的问题已得到解答并且您接受了答案,您现在无法编辑问题并提出更多问题。您需要创建一个新问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多