简体   繁体   English

Java ThreadPool 重用可运行对象而不是为每个任务创建新对象

[英]Java ThreadPool reuse runnable object instead of creating new object for each task

I'm trying to make my Dijkstra algorithm more efficient by reusing the runnable object instead of creating a new one for each task in the ThreadPool.我试图通过重用可运行对象而不是为 ThreadPool 中的每个任务创建一个新对象来提高我的 Dijkstra 算法的效率。 Each task needs 3 parameters(start value, end value and a CountDownLatch).每个任务需要 3 个参数(起始值、结束值和一个 CountDownLatch)。 I tried using getters/setters and this works everywhere except for in the run() method of the thread class.我尝试使用 getter/setter,除了在线程类的 run() 方法中,这在任何地方都有效。 It keeps reusing one variable and this screws up the algorithm它不断重复使用一个变量,这搞砸了算法

This is the thread class, the run() executes a method to look for the next closest node in the graph.这是线程类,run() 执行一个方法来寻找图中下一个最近的节点。 The variables and getters are global:变量和 getter 是全局的:

//Thread class
        class ClosestNodeTask implements Runnable {

            @Override
            public void run() {
                getNodeShortestDistanced(getStart(), getEnd(), getCdlClosest());
            }
        }

The code snippets below are executed in an apply() method.下面的代码片段在 apply() 方法中执行。

Creation of object(once):创建对象(一次):

ClosestNodeTask closestNodeTask = new ClosestNodeTask();

This snippet gives the tasks for the thread pool to execute:此代码段给出了线程池要执行的任务:

for (int t = 0; t < numberOfThreads; t++) {
      int start;
      int end;

      if (nodesModulo > 0 && numberOfThreads == (t + 1)) {
        start = nodesPerThread * (t);
        end = nodesPerThread * (t + 1) + nodesModulo;

        setStart(start);
        setEnd(end);
        setCdlClosest(cdlClosest);

        executor.execute(closestNodeTask);
      } else {
        start = nodesPerThread * t;
        end = nodesPerThread * (t + 1);

        setStart(start);
        setEnd(end);
        setCdlClosest(cdlClosest);

        executor.execute(closestNodeTask);
    }
}

The output of the 'start' variable is with two threads: 0 and 12500. If I do a getstart() in the run() of the runnable object it always returns 12500, thus messing up the algorithm. 'start' 变量的输出有两个线程:0 和 12500。如果我在可运行对象的 run() 中执行 getstart(),它总是返回 12500,从而弄乱了算法。 If I do a getstart() everywhere else I always get the correct outputs of 0 and 12500.如果我在其他地方执行 getstart() ,我总是会得到 0 和 12500 的正确输出。

What am I doing wrong?我究竟做错了什么? I don't understand why the run() method keeps reusing the same variable.我不明白为什么 run() 方法不断重复使用相同的变量。

When you create a single object and use it in multiple threads, you're essentially sharing a common state with all those threads.当您创建单个对象并在多个线程中使用它时,您实际上是在与所有这些线程共享一个公共状态。 That is, when you can setStart(), etc. you're setting the start for all running threads as well as the new one you're creating.也就是说,当您可以 setStart() 等时,您正在为所有正在运行的线程以及您正在创建的新线程设置开始。

You need separate objects for each thread.每个线程都需要单独的对象。 This is either in the form of separate instances of the class you're running or as thread-local variables, which is less efficient.这要么以您正在运行的类的单独实例的形式,要么以线程局部变量的形式存在,这样效率较低。

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

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