5

这个问题可能很容易回答,但我就是不明白。我减少了我的问题,直到留下一小段代码才能找到这个问题的“起源”:我正在尝试用循环填充线程的 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'是问题吗?

我很感激任何帮助!提前致谢!

4

3 回答 3

9

当您urun方法中引用时

@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。 . 这是因为当 newThread开始并执行时,会发生字段初始化并u立即进行评估。

于 2013-08-23T21:46:49.673 回答
1
    while (u <10) {
        synchronized(threadList){

            final int u_final = u;

            threadList.add(u, new Thread(){                
                @Override public void run(){                    
                    System.out.println("Thread at Index: " + u_final );
                } 
            });
        }
        u++;            
    }

对于final变量,它的值是什么很清楚,因为它永远不会改变。

于 2013-08-23T21:56:33.593 回答
-1

试试这两种方法:

package com.test;

import java.util.ArrayList;

public class TestThread5 {
    public static int u=0;
    public ArrayList<Thread> threadList = new ArrayList<>();
    public void test() throws InterruptedException{
        while (u <10) {
            synchronized(threadList){
                threadList.add(u, new Thread(){                
                    @Override public void run(){                    
                        System.out.println("Thread at Index: " + u);                     
                    } 
                });
            }
            u++;            
        }
        for ( u = 0; u < 10; u++) {
            Thread thread = threadList.get(u); 
            thread.start();
            thread.join();
        }
       // threadList.get(2).start();    
    }
    public static void main(String[] args) throws InterruptedException {
        new TestThread5().test();
    }
}

package com.test;

import java.util.ArrayList;
import java.util.Iterator;

public class TestThread4 {
    public  int u=0;
    public ArrayList<Thread> threadList = new ArrayList<>();
    public void test() throws InterruptedException{
        while (u <10) {
            synchronized(threadList){
                threadList.add(u, new MyThread(u));
            }
            u++;            
        }
        for(Thread thread :threadList){
            thread.start();
            thread.join();
        }
       // ((Thread) threadList.get(2)).start();    
    }
    public static void main(String[] args) throws InterruptedException {
        new TestThread4().test();
    }
}
class MyThread extends Thread{
    private int u;
    public MyThread(int u){
        this.u = u;
    }
    @Override
    public void run() {
        System.out.println("Thread at Index: " + u);  
    }

}
于 2013-08-25T00:55:21.203 回答