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

问题描述 投票:0回答:1

我正在尝试通过重用可运行对象而不是为ThreadPool中的每个任务创建一个新对象来提高Dijkstra算法的效率。每个任务需要3个参数(开始值,结束值和CountDownLatch)。我尝试使用getters / setters,除了在线程类的run()方法中,它在任何地方都有效。它不断重复使用一个变量,这弄乱了算法]

这是线程类,run()执行一个方法来查找图中的下一个最近的节点。变量和获取器是全局的:

//Thread class
        class ClosestNodeTask implements Runnable {

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

下面的代码段在apply()方法中执行。

创建对象(一次):

ClosestNodeTask closestNodeTask = new ClosestNodeTask();

此代码段提供了线程池要执行的任务:

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);
    }
}

'start'变量的输出有两个线程:0和12500。如果我在可运行对象的run()中执行getstart(),它将始终返回12500,从而弄乱了算法。如果我在其他任何地方都执行getstart(),则总会得到正确的输出0和12500。

我在做什么错?我不明白为什么run()方法不断重复使用相同的变量。

java concurrency threadpool runnable dijkstra
1个回答
0
投票

创建单个对象并在多个线程中使用它时,实际上是在与所有这些线程共享一个公共状态。也就是说,当您可以设置setStart()等时,您将为所有正在运行的线程以及正在创建的新线程设置开始。

每个线程需要单独的对象。这要么是您正在运行的类的单独实例的形式,要么是效率较低的线程局部变量。

© www.soinside.com 2019 - 2024. All rights reserved.