从内部匿名 Runnable 访问外部变量
以下示例代码 (SSCCE) 抱怨局部变量 a 必须是最终变量。
public class Foo {
final List<A> list = new ArrayList() {{ add(new A()); }};
void foo() {
A a;
Thread t = new Thread(new Runnable() {
public void run() {
a = list.get(0); // not good !
}
});
t.start();
t.join(0);
System.out.println(a);
}
class A {}
}
为了使事情正常工作,我将代码更改为该代码
public class Foo {
final List<A> list = new ArrayList() {{ add(new A()); }};
void foo() {
// A a;
final ObjectRef x = new ObjectRef();
Thread t = new Thread(new Runnable() {
public void run() {
// a = list.get(0);
x.set(list.get(0));
}
});
t.start();
t.join(0);
// System.out.println(a);
System.out.println(x.get());
}
class A {}
class ObjectRef<T> {
T x;
public ObjectRef() {}
public ObjectRef(T x) { this.x = x; }
public void set(T x) { this.x = x; }
public T get() { return x; }
}
}
我的问题:
- 这有什么问题吗?
- ObjectRef 类作为 JSE 中的标准类存在?
- 什么是正确的方法?
The following example code (SSCCE) complains that local variable a must be final.
public class Foo {
final List<A> list = new ArrayList() {{ add(new A()); }};
void foo() {
A a;
Thread t = new Thread(new Runnable() {
public void run() {
a = list.get(0); // not good !
}
});
t.start();
t.join(0);
System.out.println(a);
}
class A {}
}
To make things working i change the code to that one
public class Foo {
final List<A> list = new ArrayList() {{ add(new A()); }};
void foo() {
// A a;
final ObjectRef x = new ObjectRef();
Thread t = new Thread(new Runnable() {
public void run() {
// a = list.get(0);
x.set(list.get(0));
}
});
t.start();
t.join(0);
// System.out.println(a);
System.out.println(x.get());
}
class A {}
class ObjectRef<T> {
T x;
public ObjectRef() {}
public ObjectRef(T x) { this.x = x; }
public void set(T x) { this.x = x; }
public T get() { return x; }
}
}
My questions:
- Is there something wrong with this ?
- The ObjectRef class exists as standard class in JSE ?
- What is the right way ?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
正确的方法是使用 FutureTask 和 Callable
Right way is using FutureTask and Callable
您是否考虑过使用
Callable
来代替?当您生成结果时,可以使用 Callable ,这似乎是您的情况。Did you consider using
Callable
instead?Callable
can be used when you produce a result, which seem to be your case.我同意你应该使用 Callable 和 FutureTask。
但可能没有必要使用 Executor:如果您不打算与其他代码共享该 Executor,那么创建它、提交任务、然后再次关闭它所需的三行代码似乎太冗长了。你可以只使用一个线程。
I agree that you should go with Callable and FutureTask.
But it may not be necessary to use an Executor: If you are not going to share that Executor with other code, the three lines required to create it, submit the task, and then shut it down again, seem too verbose. You could just use a Thread.