【问题标题】:Inner FutureTask in JavaJava中的内部FutureTask
【发布时间】:2012-11-30 05:39:57
【问题描述】:

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

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 refer to a non-final variable i inside an inner class defined in a different method 但它对我不起作用。 我应该怎么做才能完成这项工作?

【问题讨论】:

    标签: java


    【解决方案1】:

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

        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(); 的调用将阻塞,直到任务完成。

    【讨论】:

    • 我有一个类似的用例,试图将 AsyncTasks 转换为 ExecutorService 以从 Room 数据库返回一个列表。另一个答案建议在 ExecutorService 上使用 submit(),在 Dao 方法上使用 get()(请参阅 stackoverflow.com/questions/52242933/room-database-query)。非常感谢您对该方法与使用 Callable 和 Future 的方法的想法。
    • @AJE 我建议您单独提出一个问题并提供相关详细信息。
    【解决方案2】:

    您可能想使用Callable,而不是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
    

    【讨论】:

      猜你喜欢
      • 2013-01-20
      • 1970-01-01
      • 2013-08-20
      • 2011-06-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多