java - 从内部匿名 Runnable 访问外部变量

标签 java multithreading anonymous-class

以下示例代码 (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; }
    }
}

我的问题:

  1. 这有什么问题吗?
  2. ObjectRef 类作为标准类存在于 JSE 中?
  3. 什么是正确的方法?

最佳答案

正确的方法是使用 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();

关于java - 从内部匿名 Runnable 访问外部变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2295392/

相关文章:

java - 关于java中==运算符的问题

java - 从服务更新 textView 的最简单方法是什么?

java - 如何使用不同的延迟参数持续更新textView

匿名对象方法的Javadoc

java - 这段 Java 代码片段到底发生了什么?

java - 我应该如何从 xml 中的 Apache Jackrabbit 中的节点中提取属性?

java - ImageView 上的透明背景 EditText 不会显示光标

java - 错误提交响应 java.io.IOException : Broken pipe at sun. nio.ch.FileDispatcher.write0(Native Method)

c++ - 有效地等待线程池中的所有任务完成

c# - 序列化匿名委托(delegate)列表