gpt4 book ai didi

java - 匿名 Runnable 中使用的最终 int 参数

转载 作者:太空宇宙 更新时间:2023-11-03 12:36:34 26 4
gpt4 key购买 nike

我想知道我是否使用正确的方法在不同的线程中调用某些东西。我是在 Android 上做的,但认为这是一般的 Java 问题。

我有一些参数的方法。假设它们是整数。

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 从 native 调用 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);
}
});
}

通过这种方式,我可以保护值免受垃圾收集,直到使用并丢弃 runnable。我是否必须创建包装器,或者在方法参数中标记 final x 是否安全?当我尝试时,final 关键字工作得很好。但是在线程中,我不认为它现在是否有效是它永远有效的原因。它总是与 final 一起工作吗?如果有的话是怎么做出来的?如果参数不是原始类型,而是对象,会有区别吗?

更新:我已经了解 final 在 Java 中的含义。这不是问题所在。问题点是在创建 Runnable 时使用的变量范围在哪里。它们是局部变量,这意味着在函数结束后无法引用它们的值。当 Runnable 对象被传递给其他线程并等待执行时,这些值存储在哪里?

最佳答案

在线程内部获取参数和局部变量(驻留在方法调用堆栈上)的副本。这是因为在方法调用完成后,线程仍然存在。

并且要求变量是final的,禁止在方法中覆盖原来的变量,导致线程中有不同的版本。这简直是​​误导。因此,让同名的两个版本表示同一事物是一个问题。

精心的语言设计。

(稍微简化,不命名对称颠倒的情况,同样成立。)

关于java - 匿名 Runnable 中使用的最终 int 参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17812498/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com