我想知道我是否使用了正确的方法在不同的线程中调用某些东西。我正在Android上进行操作,但认为这是通用的Java问题。
我有一个带有一些参数的方法。假设它们是int。
class Main1 {
public static void mainOnlyWork(int x, int y) {
// not important here.
}
}
class Test {
Handler mHandler;
// called from main thread, stored as reference.
public Test() {
mHandler = new Handler();
}
public static void callInMainThread(final int x, final int y) {
mHandler.post(new Runnable() {
public void run() {
Main1.mainOnlyWork(x, y);
}
});
}
现在我的问题是,是否可以安全地使用final int来创建匿名runnable而不使用任何类成员?如果我省略了x和y参数的final关键字,Eclipse会发出警告。在这种情况下,似乎只能使用常数。如果我传递的不是常数,可以吗?Java会通过将其传递给此函数来“使”它成为常数吗?
但是我想从本机使用JNI调用Test.callInMainThread。在我看来,Java无法判断这些数字是否为常量。我能相信Java会进行一些魔法吗?它总是这样工作吗?
我认为也许我必须创建代理类,像:
private abstract RunnableXY implements Runnable {
public RunnableXY(int x, int y) {
this.x = x;
this.y = y;
}
public int x;
public int y;
public abstract void run();
}
并且调用方法将会使用:
public static void callInMainThread(final int x, final int y) {
mHandler.post(new RunnableXY(x,y) {
public void run() {
Main1.mainOnlyWork(this.x, this.y);
}
});
}
这样,我可以保护值免受垃圾回收,直到可运行对象被使用和丢弃。我需要创建包装器吗?还是在方法参数中标记final x是安全的?当我尝试时,final关键字可以正常工作。但是在线程中,我不认为它现在能够工作就意味着它将永远工作。final总是有效吗?如果有效,它是如何实现的?如果参数不是基本类型而是对象,会有区别吗?
更新: 我已经了解了Java中final的含义。这不是问题的重点。问题的重点是Runnable的创建中使用的变量的范围在哪里。它们是局部变量,这意味着在函数结束后它们的值不能被引用。那么当Runnable对象传递到其他线程并等待执行时,这些值存储在哪里?