以下示例代码(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; }
}
}
我的问题:
答案 0 :(得分:4)
正确的方法是使用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();
答案 1 :(得分:3)
您是否考虑过使用Callable
?当您生成结果时,可以使用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() );
}
答案 2 :(得分:2)
我同意你应该使用Callable和FutureTask。
但是可能没有必要使用Executor:如果你不打算与其他代码共享Executor,那么创建它,提交任务然后再将其关闭所需的三行似乎过于冗长。你可以使用一个线程。
FutureTask<A> task = new FutureTask(new Callable<A>() {
public A call() {
return list.get(0);
}
});
new Thread(task).start();
A result = task.get();