向Java线程传递参数

7
Thread t = new Thread(new Runnable() { public void run() {} });

我希望以这种方式创建一个线程。如果可能的话,我如何将参数传递给run方法? 编辑:为了让我的问题更具体化,请考虑以下代码片段:
for (int i=0; i< threads.length; i++) {
    threads[i] = new Thread(new Runnable() {public void run() {//Can I use the value of i in the method?}});
}

根据Jon的回答,这个方法行不通,因为i没有被声明为final

2
如果可能的话,编写一个实现Runnable接口的新类,并在构造函数中传递所有需要的参数会更容易些。 - giocarmine
在IntelliJ中,它有一个自动纠正功能。它会为您将匿名类中使用的变量分配给final变量。 - Peter Lawrey
我建议您使用THRAEDLOCAL,这是一种更好的方法来保留和传递变量给线程,请尝试一下,可能会得到更好的结果。 - Hussain Akhtar Wahid 'Ghouri'
Jon的答案是可行的,你只需要在循环内部将i的值分配给一个final本地变量。我也赞同建议去研究使用ExecutorService。 - Gustav Grusell
2个回答

10
不,run方法从未有任何参数。您需要将初始状态放入Runnable中。如果您使用的是匿名内部类,可以通过一个final局部变量来实现:
final int foo = 10; // Or whatever

Thread t = new Thread(new Runnable() {
    public void run() {
        System.out.println(foo); // Prints 10
    }
});

如果您正在编写一个命名类,请在类中添加一个字段,并在构造函数中填充它。
或者,您可能会发现java.util.concurrent中的类更有帮助(例如ExecutorService等),这取决于您想要做什么。
编辑:为了将上述内容放入您的上下文中,您只需要在循环内部使用一个final变量即可。
for (int i=0; i< threads.length; i++) {
    final int foo = i;
    threads[i] = new Thread(new Runnable() {
         public void run() {
             // Use foo here
         }
    });
}

我刚刚提供了一些关于我正在尝试做什么的背景信息。 - Terry Li
@TerryLi:查看我的编辑,了解如何在循环内使用我的第一种方法。或者只需使用一个命名类... - Jon Skeet

5
您可以创建一个接受您参数的自定义线程对象,例如:
public class IndexedThread implements Runnable {
    private final int index;

    public IndexedThread(int index) {
        this.index = index;
    }

    public void run() {
        // ...
    }
}

这可以像这样使用:

IndexedThread threads[] = new IndexedThread[N];

for (int i=0; i<threads.length; i++) {
    threads[i] = new IndexedThread(i);
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接