一个线程完成任务后,如何告诉线程池中的其他线程停止?

How can I tell other threads in threadpool to stop after one thread completes the task?

这是我的代码:

class Processor implements Runnable {

    private int id;
    private Integer interaction;
    private Set<Integer> subset;
    Iterator<Integer> iterator;
    ArrayList<Integer> par;

    public Processor(int id, Integer interaction, Set<Integer> subset, Iterator<Integer> iterator, ArrayList<Integer> par) {
        this.id = id;
        this.interaction = interaction;
        this.subset = subset;
        this.par = par;
        this.iterator = iterator;
    }

    public void run() {
        System.out.println("Starting: " + this.id);
        if (this.par.contains(this.interaction)) {
            this.subset.add(this.interaction);
            increaseScore(this.subset);
            if (!this.subset.contains(this.interaction)) {
                //TELL ALL OTHER THREADS TO STOP WHILE THIS THREAD REMOVES THE VALUE FROM THE ITERATOR
                iterator.remove();
            }
        }

        System.out.println("Completed: " + this.id);

    }
}

public class ConcurrentApp {

    public static void main(String[] args) {

        ExecutorService executor = Executors.newFixedThreadPool(4);
        ArrayList<Integer> par1 = new ArrayList < Integer > ();
        long start = System.nanoTime();

        int i = 1;
        while ((par1.size() > i)) {
            for (Iterator<Integer> iterator = par1.iterator(); iterator.hasNext();) {
                Integer interaction = iterator.next();
                ArrayList<Integer> removed = new ArrayList<Integer> (par1);
                removed.remove(interaction);
                ArrayList<Set<Integer>> subsets = getSubsets(removed, i);
                for (int j = 0; j < subsets.size(); j++) {
                    executor.submit(new Processor(j, interaction, subsets.get(j), iterator, par1));
                }
                executor.shutdown();
                System.out.println("All tasks submitted");
                try {
                    executor.awaitTermination(1, TimeUnit.DAYS);
                } catch(InterruptedException e) {
                    e.printStackTrace();
                }
            }
            System.out.println("All tasks completed");
            i++;
        }
        long end = System.nanoTime();

        System.out.println("Program Completed in: " + (end - start) * 0.000000001);

    }
}

我的代码流程如下:

  1. 从一个名为 par 的整数 ArrayList 开始,遍历此集合中的每个元素(我们称其为 A)

  2. 从par中去掉A得到B

  3. 找到大小为 i 的所有子集(在 1 到 par.size() 范围内)

  4. [Multithreaded]对于每个大小为i的子集,在A中加回去得到一个新的集合C。然后求删除时增加的值C的分数最多。 [条件]如果该值为 A,则从 par 中删除 A 并移至 par 中的下一个元素。如果对于任何大小为 i 的子集都没有删除 A,则继续 par.

  5. 中的下一个元素

我的意图是让每个线程与其中一个子集一起工作,并执行上面的 多线程 步骤,直到其中一个线程满足 条件.我认为我正确地实现了这一点,但由于我是并发编程的新手,所以希望能多多关注。

问题1:在上面的多线程步骤中,如何告诉线程池中的所有其他工作线程停止他们的任务并在单个线程后返回线程池满足条件

问题 2: 有没有办法让多个线程同时处理不同大小的子集的不同集合(因此一次有多个 i 值)并且有多个线程对给定的一组子集执行上面的多线程步骤(这是我已经完成的)?从本质上讲,这就像将我的整个工作分成两个任务:任务 1 是查看大小为 1、2、3...par.size() 的子集集,任务 2 是查看一组子集。

感谢您的帮助!

Q1:使用一个易失性静态变量(可能是一个易失性 AtomicLong),所有线程都可以检查是否完成,并在完成 activity.

时更新

Q2:绝对有可能。您已经设置了一个 Runnable,它可以采用您的 Shapes 和要处理的子集大小范围。但据我所知,这可能有点矫枉过正:任务 2(你已经完成的部分)需要比任务 1 多得多的处理能力,所以你最好保持原样现在

如果我误解了你的问题,请告诉我

问题1:在上面的多线程步骤中,我怎样才能告诉线程池中的所有其他工作线程停止他们的任务并在单个线程后返回线程池符合条件?

使用 invokeAny API 共 ExecutorService

<T> T invokeAny(Collection<? extends Callable<T>> tasks,
                long timeout,
                TimeUnit unit)
         throws InterruptedException,
                ExecutionException,
                TimeoutException

Executes the given tasks, returning the result of one that has completed successfully (i.e., without throwing an exception), if any do before the given timeout elapses. Upon normal or exceptional return, tasks that have not completed are cancelled. The results of this method are undefined if the given collection is modified while this operation is in progress.

问题 2: 有没有办法让多个线程同时处理不同大小的子集的不同集合(因此一次有多个 i 值)并且有多个线程对给定的一组子集执行上面的多线程步骤(这是我已经完成的)?

你可以用 .如果您在实施上述过程中遇到任何问题,请分享您的问题。即使要等待所有任务完成,也可以使用invokeAll. If you want to improve the performance, you can use ForkJoinPool