我遇到Runnable类的问题。传递给runnable类的值将被相同值传递给另一个类时收到的最后一个值覆盖。 runnable类的功能是将值传递给另一个类中的另一个函数来打印它们。但只打印Runnable类收到的最后一个值。
这是我的代码, 这是传递值的主要类。
-F
这是我用来调用线程的executorUtil。
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));
}
}
}
}
这是将接收到的值传递给打印这些值的函数的线程。
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
不知道为什么这样做会这样!
更新
仅在使用非原始数据类型时才会出现此问题。在我的例子中,我使用了一个整数值(intVal)。由于java传递了原始数据类型的值,因此按预期获得了输出。但在我的原始代码中,我使用了JSONObject。由于java为非原始数据类型传递了对象的引用,因此该值被覆盖。
我通过为每次迭代创建新的JSONObject来解决这个问题。
答案 0 :(得分:0)
似乎某个地方有静态字段,用于存储您的号码。 所以,我想,你有3个ActionExecutor实例,但看起来field有静态修饰符,所以每个实例都有最新的值。
检查此案例......
答案 1 :(得分:0)
所以在我阅读你的问题并研究你的代码后,我不妨试一试。并且看到它按预期工作。这里唯一的区别是存在竞争条件,因此输出我的顺序不同,但它不会打印相同的数字。 输出可能
0 1 2
0 1 2
2 1 0
以下是试用它的完整代码:
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
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));
}
}
}
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);
}
}
public static 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 static void main(String[] args) {
MainClass main = new MainClass();
main.MainMethod();
}
}
您可能希望清理并重建项目。否则它正在工作..