Java线程池重用可运行对象,而不是为每个任务创建新对象
我试图通过重用runnable对象,而不是为线程池中的每个任务创建一个新的对象,来提高Dijkstra算法的效率。每个任务需要3个参数(开始值、结束值和倒计时锁存)。我尝试使用getter/setter,除了在thread类的run()方法中,这在任何地方都有效。它不断地重复使用一个变量,这就把算法搞砸了 这是thread类,run()执行一个方法来查找图中下一个最近的节点。变量和getter是全局的:Java线程池重用可运行对象,而不是为每个任务创建新对象,java,concurrency,threadpool,runnable,dijkstra,Java,Concurrency,Threadpool,Runnable,Dijkstra,我试图通过重用runnable对象,而不是为线程池中的每个任务创建一个新的对象,来提高Dijkstra算法的效率。每个任务需要3个参数(开始值、结束值和倒计时锁存)。我尝试使用getter/setter,除了在thread类的run()方法中,这在任何地方都有效。它不断地重复使用一个变量,这就把算法搞砸了 这是thread类,run()执行一个方法来查找图中下一个最近的节点。变量和getter是全局的: //Thread class class ClosestNodeTask i
//Thread class
class ClosestNodeTask implements Runnable {
@Override
public void run() {
getNodeShortestDistanced(getStart(), getEnd(), getCdlClosest());
}
}
下面的代码段在apply()方法中执行
创建对象(一次):
此代码段提供线程池要执行的任务:
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);
}
}
for(int t=0;t0&&numberOfThreads==(t+1)){
start=nodesPerThread*(t);
end=nodesPerThread*(t+1)+nodesModulo;
设置启动(启动);
setEnd(end);
设置cdlClosest(cdlClosest);
执行者。执行(关闭节点任务);
}否则{
start=nodesPerThread*t;
end=nodesPerThread*(t+1);
设置启动(启动);
setEnd(end);
设置cdlClosest(cdlClosest);
执行者。执行(关闭节点任务);
}
}
“start”变量的输出有两个线程:0和12500。如果我在runnable对象的run()中执行getstart(),它总是返回12500,从而打乱了算法。如果我在其他地方执行getstart(),我总是得到正确的输出0和12500
我做错了什么?我不明白为什么run()方法总是重复使用同一个变量 当您创建一个对象并在多个线程中使用它时,您实际上与所有这些线程共享一个公共状态。也就是说,当您可以设置start()等时,您将为所有正在运行的线程以及正在创建的新线程设置开始
每个线程都需要单独的对象。这要么是以正在运行的类的单独实例的形式,要么是以线程局部变量的形式,效率较低。换句话说,您无法按照所描述的方式优化代码,因为这样做会引入与您发现的错误完全相同的错误。您已经在一开始就指出了您做错的地方:“我正试图通过重用可运行对象来提高Dijkstra算法的效率”。当您重用对象时,算法不会变得更有效。当“每个任务需要3个参数”时,您必须为每个任务创建一个包含3个参数的对象,这是一件基本且琐碎的事情。
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);
}
}