我想在循环中创建新的Runnable
。但是,不可能在内部类中使用变量。我不能使用global / instance变量,因为它会产生错误的结果。我的程序类似于以下简化代码:
public class RunManager {
public void runManager(int delay, final Context context) {
for (int dim = 7; dim < 227; dim++) {
Runnable r = new Runnable() {
@Override
public void run() {
RandomKernels randomKernels = new RandomKernels();
try {
randomKernels.foo(context, dim);
} catch (InterruptedException e) {
Log.e(tag, e.getMessage());
}
}
};
Thread cnnThread = new Thread(r);
cnnThread.start();
try {
Thread.sleep(delay);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
错误是:Variable 'dim' is accessed from within inner class, needs to be declared final.
答案 0 :(得分:1)
您的问题是您正在尝试从新线程访问非最终变量。为了从新线程中加入变量,需要将其声明为final。在你的cas中,你可以将dim int复制到大小为1的final int数组,然后从线程访问该数组。
答案 1 :(得分:0)
可能最简单的方法是为Runnable
创建一个接受int作为参数的构造函数。如:
public class MyRunnable implements Runnable {
public MyRunnable(Context context, int dim) {
// save parameters as class variables
}
public void run() {
// do the work
}
}
然后叫它:
Runnable r = new MyRunnable(context, dim);
new Thread(r).start();
答案 2 :(得分:0)
如果您想要访问内部类中的值,则应使用final int[] dim
。
public class RunManager {
public void runManager(int delay, final Context context) {
for (final int dim[] = {7}; dim[1] < 227; dim[1]++) {
Runnable r = new Runnable() {
@Override
public void run() {
RandomKernels randomKernels = new RandomKernels();
try {
randomKernels.foo(context, dim[1]);
} catch (InterruptedException e) {
Log.e(tag, e.getMessage());
}
}
};
Thread cnnThread = new Thread(r);
cnnThread.start();
try {
Thread.sleep(delay);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
选项2 - 使用字段:
public class RunManager {
private int _dim;
public void runManager(int delay, final Context context) {
for (int dim = 7; dim < 227; dim++) {
_dim = dim;
Runnable r = new Runnable() {
@Override
public void run() {
RandomKernels randomKernels = new RandomKernels();
try {
randomKernels.foo(context, _dim);
} catch (InterruptedException e) {
Log.e(tag, e.getMessage());
}
}
};
Thread cnnThread = new Thread(r);
cnnThread.start();
try {
Thread.sleep(delay);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
选项3 - 在另一个方法中迭代并添加final int dim
作为方法参数:
private void createThreads(int delay, final Object context) {
for (int dim = 7; dim < 227; dim++) {
runManager(delay, context, dim);
}
}
public void runManager(int delay, final Context context, final int dim) {
Runnable r = new Runnable() {
@Override
public void run() {
RandomKernels randomKernels = new RandomKernels();
try {
randomKernels.foo(context, dim);
} catch (InterruptedException e) {
Log.e(tag, e.getMessage());
}
}
};
Thread cnnThread = new Thread(r);
cnnThread.start();
try {
Thread.sleep(delay);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
选项4 - 使用自定义runnable。您可以按照@BMacedo的建议实现类,也可以在内部类中创建抽象类和实现逻辑。
public class RunManager {
public void runManager(int delay, final Context context) {
for (int dim = 7; dim < 227; dim++) {
CustomRunnable r = new CustomRunnable() {
private int _dim;
@Override
public void run() {
RandomKernels randomKernels = new RandomKernels();
try {
randomKernels.foo(context, _dim);
} catch (InterruptedException e) {
Log.e(tag, e.getMessage());
}
}
public void setDim(int dim) {
_dim = dim;
}
};
r.setDim(dim);
Thread cnnThread = new Thread(r);
cnnThread.start();
try {
Thread.sleep(delay);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
abstract class CustomRunnable implements Runnable {
public abstract void setDim(int dim);
}
}