【问题标题】:Need help returning object in thread run method需要帮助在线程运行方法中返回对象
【发布时间】:2011-01-19 00:23:36
【问题描述】:

我有一个扩展 Thread 的 Java 类,它基本上如下所示:

public class HttpRequestDispatcher extends Thread {
    private String url;
    private String method; // GET or POST
    private byte[] postData;

    public HttpRequestDispatcher(String url, String method, byte[] postData) {
        this.url = url;
        this.method = method;
        this.postData = postData;
    }

    public HttpRequestDispatcher(String url, String method) {
        this.url = url;
        this.method = method;
    }

    public void run() {
        ...
    }
}

我需要run() 方法来返回ByteArrayOutputStreamString。但是,因为在Threadrun()方法中,所以无法将方法的返回类型设置为ByteArrayOutputStreamString

HttpRequestDispatcher 类在名为 OAuth.java 的类中调用。

我该如何解决这种情况?

【问题讨论】:

    标签: java multithreading methods return


    【解决方案1】:

    让它实现Callable<T> 而不是ThreadRunnable。这里T 必须代表结果的类型。使用ExecutorService 执行它。它将以Future<V> 的形式返回结果。

    这是一个 SSCCEString 作为T,只需复制'n'paste'n'运行它。

    package com.stackoverflow.q2300433;
    
    import java.util.Arrays;
    import java.util.List;
    import java.util.concurrent.Callable;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    import java.util.concurrent.Future;
    
    public class Test {
        public static void main(String... args) throws Exception {
            ExecutorService executor = Executors.newSingleThreadExecutor();
            Future<String> future = executor.submit(new Task());
            System.out.println(future.get()); // Prints "result" after 2 secs.
    
            // Or if you have multiple tasks.
            // List<Future<String>> futures = executor.invokeAll(Arrays.asList(new Task()));
            // for (Future<String> future : futures) {
            //     System.out.println(future.get());
            // }
    
            executor.shutdown(); // Important!
        }
    }
    
    class Task implements Callable<String> {
        public String call() throws Exception {
            Thread.sleep(2000);
            return "result";
        }
    }
    

    【讨论】:

    • 我正计划尝试这种方法。如果您查看我对以下帖子的评论,您将看到线程将完成的两种情况......它将成功并返回一个 ByteArrayOutputStream,或者它将失败并返回一个流。这是接受不同类型对象的好方法吗?我正在寻找多功能性 - 会有很多不同的类使用这个 HttpRequestDispatcher
    • 抽象化并命名为HttpResponse。它会变得更简单。
    • 我用过它,它可以很好地返回结果。除了 executor.shutdown 没有帮助我处理并发呼叫。我收到“进程无法访问该文件,因为它正在被另一个进程使用”的错误。在我的 call() 方法中,我运行一个调用 exe 的进程,然后从该进程复制一个字节数组并返回它。有什么想法吗?
    【解决方案2】:

    这个问题有几种解决方案:

    • 使用线程外部的数据结构。当你的线程即将完成时,在你的构造函数中传递对象并更新它。

    • 使用回调方法。当您的线程完成时,调用回调。

    • 使用java.util.concurrent.Future (Java >= 1.5):

      Future 表示异步计算的结果。提供了检查计算是否完成、等待其完成以及检索计算结果的方法。

    【讨论】:

    • 使用回调方法的方法:HttpRequest成功或失败时线程将结束。所以假设我有两个方法:requestSucceeded 和 requestFailed。线程将根据其结果调用这些方法之一。我的一个问题是如何将 requestSucceeded 或 requestFailed 的结果返回到最初启动线程的 OAuth.java 中的原始方法?谢谢!
    • 您可以,例如,在 OAuth.java 中定义您的回调。将 OAuth 对象向下传递给线程。然后,根据结果,调用适当的回调。如果您需要将多个线程分派到不同的操作,回调函数可以接受“发送者”作为参数之一。这只是一个想法..
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-09
    • 2019-12-22
    相关资源
    最近更新 更多