【发布时间】:2017-10-06 14:06:52
【问题描述】:
我遇到了 Runnable 类的问题。当相同的值传递给另一个类时,传递给可运行类的值将被它收到的最后一个值覆盖。 可运行类的功能是将值传递给另一个类中的另一个函数以打印它们。但只打印 Runnable 类收到的最后一个值。
这是我的代码, 这是传递值的主类。
public class MainClass {
private int intVal = -1;
public void MainMethod() {
ExecutorUtil theExecutor = ExecutorUtil.GetInstance();
for(int i = 0; i < 3; i++) {
intVal = i;
synchronized (this) {
theExecutor.SubmitTask(new ActionExecutor(intVal));
}
}
}
}
这是我用来调用线程的 executorUtil。
import java.util.concurrent.ExecutorService;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.BlockingQueue;
public class ExecutorUtil {
private static ExecutorUtil theInstance;
private ExecutorService theExecutor;
private BlockingQueue<Runnable> theQueue;
protected ExecutorUtil() {
theExecutor = CreateThreadPoolExecutor();
}
private ExecutorService CreateThreadPoolExecutor() {
theQueue = new LinkedBlockingQueue<Runnable>();
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(10, 10, 900, java.util.concurrent.TimeUnit.SECONDS, theQueue);
threadPoolExecutor.allowCoreThreadTimeOut(true);
return threadPoolExecutor;
}
public static ExecutorUtil GetInstance() {
if (theInstance == null) {
synchronized(ExecutorUtil.class) {
if (theInstance == null) {
theInstance = new ExecutorUtil();
}
}
}
return theInstance;
}
public void SubmitTask(Runnable runnable) {
theExecutor.submit(runnable);
}
}
这是将接收到的值传递给打印这些值的函数的线程。
public class ActionExecutor implements Runnable {
int iVal = -1;
public ActionExecutor(int iVal) {
this.iVal = iVal;
}
public void run() {
SecondClass sc = new SecondClass();
sc.printIntVal(iVal);
}
}
这是打印值的类。
public class SecondClass {
public void printIntVal(int i) {
System.out.println(i);
}
}
预期输出:
0
1
2
获得的输出:
2
2
2
不知道为什么会这样!
更新:
仅当使用非原始数据类型时才会出现此问题。在我的示例中,我使用了一个整数值 (intVal)。由于 java 传递原始数据类型的值,因此按预期获得了输出。但在我的原始代码中,我使用了 JSONObject。并且由于 java 为非原始数据类型传递对象的引用,因此该值被覆盖。
我通过为每次迭代创建新的 JSONObject 解决了这个问题。
【问题讨论】:
-
一般来说,你的代码包含很多不正确的多线程解决方案,会导致各种微妙的难以解决的情况。除此之外,您使用的代码约定与 Java 开发中的标准相去甚远,导致代码难以阅读。
-
其实这不是原始代码。我把原代码简化了,方便其他SO用户理解我的问题!
标签: java multithreading executorservice