java - 遍历通过 ThreadPoolTask​​Executor 运行的线程

标签 java multithreading

我有一个 ThreadPoolTask​​Executor,当我创建一个实现 RunnableProcess 时,我通过以下方式运行它:executor.execute(process )

现在,在调用 execute 之前,我想检查 Process 对象中的一个字段,并将其与所有其他 当前运行 进程进行比较,由我的 ThreadPoolTask​​Executor。我如何做到这一点,而不产生并发问题?

代码:

public class MyApp {

   ThreadPoolTaskExecutor executor;

   //...

   public void runProcesses {
       Process firstone = new Process(1);
       Process nextOne = new Process(1);


       // iterate through all processes started via executor and currently running,
       // verify if there is any process.getX() == 1, if not run it

       executor.execute(firstone );

       //wait till firstone will end becouse have the same value of X
       executor.execute(nextOne); // this cant be perform until the first one will end
   }
}

public class Process {
    private int x;

    //...

    public Process (int x){
        this.x = x;
    }
    public int getX(){
         return this.x;
    }

}

我正在考虑创建简单的 Set 流程启动并向其中添加新流程。但是我有问题如何确定它是否仍在运行并在完成后将其从集合中删除。所以现在我正在考虑遍历正在运行的线程,但完全不知道怎么做。

最佳答案

我认为您最初的想法非常好,无需太多代码即可实现。 它需要一些修补才能将“是一个 Runnable 对于这个值已经运行”从“执行这个 Runnable” 中分离出来,但这里有一个粗略的例子,没有考虑到这一点:

  • 实现 equals()hashCode()Process ,以便实例可以安全地用于无序集和映射。
  • 创建 ConcurrentMap<Process, Boolean>
    • 您不会使用 Collections.newSetFromMap(new ConcurrentHashMap<Process, Boolean>)因为你想使用 map 的 putIfAbsent()方法。
  • 尝试使用 putIfAbsent() 添加进去每个Process如果返回值不是 null,您将提交并保释.
    • null返回值意味着已经有一个等价的 Process在 map 中(因此正在处理中)。
    • 简单且不是很干净的解决方案是在每个 Process 中注入(inject)对 map 的引用。实例并有putIfAbsent(this, true)作为你在 run() 中做的第一件事方法。
  • 从中删除每个 Process已经完成处理。
    • 简单且不是很干净的解决方案是在每个 Process 中注入(inject)对 map 的引用。实例并有remove(this)作为你在 run() 中做的最后一件事方法。
    • 其他解决方案可以有Process实现 Callable并返回其唯一值作为结果,以便可以将其从 map 中删除,或使用 CompletableFuture及其 thenAccept()回调。

Here's一个示例,说明了上述简单且不是很干净的解决方案(代码太长,无法直接粘贴到此处)。

关于java - 遍历通过 ThreadPoolTask​​Executor 运行的线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36642539/

相关文章:

c# - 如何启动一个线程来保持GUI刷新?

java - 如何对java中ExecutorService内部的相似线程求和?

java - 使用比硬件线程更多的线程时的注意事项?

java - 为什么 Spinner 不触发 onItemselected?

java - 没有可用的托管连接

java - 是否可以在 android 中合并未知数量的 firestore 查询?

java - 如何改进抛出 "statement timeout"的 postgresql 请求

java - 如何对无法存储在一个变量中的大数字进行操作

c# - 线程和复制文件应该使用哪些方法?

c# - 高性能缓存