这个问题可能很容易回答,但我就是不明白。 我减少了我的问题,直到留下这一小段代码以找到这个问题的“起源”: 我正在尝试用循环填充线程的 ArrayList。
public static int u=0;
public void test(){
while (u <10) {
synchronized(threadList){
threadList.add(u, new Thread(){
@Override public void run(){
System.out.println("Thread at Index: " + u);
}
});
}
u++;
}
threadList.get(2).start();
}
在最后一行中,我想通过在索引“2”处启动线程来测试上面的循环。 我希望控制台显示“索引处的线程:2”,但显示的是: “索引处的线程:10” 无论我在“.get(int)”方法中写入哪个整数,我都会收到索引“10”。
这是为什么呢?以及如何解决这个问题?
线程的创建似乎有效...那么整数“u”是问题所在吗?
我感谢任何形式的帮助! 提前致谢!
最佳答案
当您在run
方法中引用u
@Override public void run(){
System.out.println("Thread at Index: " + u);
}
检索到 u
的当前值。在循环结束时以及线程运行时,该值为 10
。
尝试以下操作
public static int u = 0;
public void test(){
while (u <10) {
synchronized(threadList){
threadList.add(u, new Thread(){
int i = u;
@Override public void run(){
System.out.println("Thread at Index: " + i);
}
});
}
u++;
}
threadList.get(2).start();
}
在您的匿名 Thread
类中,您将实例字段 i
设置为 u
在构造函数被调用和打印时具有的值执行 run()
时的那个值。
您在尚未执行的上下文(线程)中引用 u
。当 run()
方法最终被调用时,程序将计算变量 u
,但在程序执行的那一刻,它的值将为 10。如果,相反,您执行上述操作,变量 i
将保存该时刻的值。这是因为当新的 Thread
启动并执行时,字段初始化发生并且 u
立即被评估。
关于Java - 用循环填充线程的 ArrayList,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18412308/