2

我尝试实现一个内部方法,以便在新线程中执行以下代码

MyPojo result = null;
final MyPojo result2 = result;

FutureTask<MyPojo> runnableTask = new FutureTask<MyPojo>(
    new Runnable() {  

        BindJSON<MyPojo> binding;

        // Make the URL at which the product list is found
        String sourceURLString = 
            "http://www.....ca/files/{CAT_ID}.json";                

        @Override
        public void run() {  
            sourceURLString = sourceURLString.replace("{CAT_ID}", catId);
            binding = new BindJSON<MyPojo>();  
            result2 = binding.downloadData(sourceURLString, MyPojo.class);  
        }  
    }, 
    result2);

runnableTask.run();

所以,现在我收到一条错误消息:无法分配最终的局部变量 result2,因为它是在封闭类型中定义的。我看一下这个答案:Cannot reference a non-final variable i inside an internal class defined in a different method但它对我不起作用。我应该怎么做才能完成这项工作?

4

2 回答 2

4

您可能想使用 a Callable,而不是 a Runnable

// the variable holding the result of a computation
String result = null;

FutureTask<String> runnableTask = new FutureTask<String>(
        new Callable<String>() {
            public String call() throws Exception {
                // (asynchronous) computation ...
                return "42";
            }
        });

System.out.println("result=" + result); // result=null

// this will invoke call, but it will all happen in the *same thread*
runnableTask.run();

// to have a parallel thread execute in the 'background'
// you can use java.util.concurrent.Executors
// Note: an ExecutorService should be .shutdown() properly
// Executors.newSingleThreadExecutor().submit(runnableTask);

// waits for the result to be available
result = runnableTask.get();

// you can also add timeouts:
// result = runnableTask.get(100, TimeUnit.MILLISECONDS);

System.out.println("result=" + result); // result=42
于 2012-12-12T13:53:08.977 回答
3

您对 FutureTask 的使用不是很有用,因为您在同一个线程中执行它。您可以使用执行程序并提交可调用来实现您想要的:

    ExecutorService executor = Executors.newFixedThreadPool(1);

    Callable<MyPojo> task = new Callable<MyPojo> () {
        BindJSON<MyPojo> binding;
        // Make the URL at which the product list is found
        String sourceURLString = "http://www.....ca/files/{CAT_ID}.json";

        @Override
        public MyPojo call() {
            sourceURLString = sourceURLString.replace("{CAT_ID}", catId);
            binding = new BindJSON<MyPojo>();
            return binding.downloadData(sourceURLString, MyPojo.class);
        }
    };

    Future<MyPojo> future = executor.submit(task);
    MyPojo result = future.get();

注意:调用future.get();将阻塞,直到任务完成。

于 2012-12-12T13:52:51.303 回答