[英]Access outer variable from inner anonymous Runnable
The following example code (SSCCE) complains that local variable a must be final. 以下示例代码(SSCCE)抱怨局部变量a必须是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: 我的问题:
Right way is using FutureTask and Callable 正确的方法是使用FutureTask和Callable
FutureTask task = new FutureTask(new Callable<A>() {
public A call() {
return list.get(0);
}
});
Executor ex = Executors.newFixedThreadPool(1);
ex.execute(task);
// do something else, code is executing in different thread
A a = task.get(); //get result of execution, will wait if it's not finished yet
ex.shutdown();
Did you consider using Callable
instead? 您是否考虑过使用Callable
? Callable
can be used when you produce a result, which seem to be your case. 当你产生一个结果时,可以使用Callable
,这似乎是你的情况。
final List<A> list = new ArrayList() {{ add(new A()); }};
void foo() {
Callable<A> call = new Callable<A> {
A call() throws Exception
{
// do something with the list
return list.get(0);
}
}
ExecutorService executor = new ScheduledThreadPoolExecutor(1);
Future<A> future = executor.submit(call);
System.out.println( future.get() );
}
I agree that you should go with Callable and FutureTask. 我同意你应该使用Callable和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. 但是可能没有必要使用Executor:如果你不打算与其他代码共享该Executor,那么创建它,提交任务然后再将其关闭所需的三行似乎过于冗长。 You could just use a Thread. 你可以使用一个线程。
FutureTask<A> task = new FutureTask(new Callable<A>() {
public A call() {
return list.get(0);
}
});
new Thread(task).start();
A result = task.get();
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.