I have a Java class that extends Thread
, it basically looks like the following:
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() {
...
}
}
I need the run()
method to return a ByteArrayOutputStream
or a String
. However, because it is in the run()
method of the Thread
, I cannot set the return type of the method to a ByteArrayOutputStream
or a String
.
The HttpRequestDispatcher
class is called inside of a class called OAuth.java.
How can I get around this situation?
Let it implement Callable<T>
instead of Thread
or Runnable
. Here T
must represent the type of the result. Use ExecutorService
to execute it. It will return the result in flavor of a Future<V>
.
Here's an SSCCE with String
as T
, just copy'n'paste'n'run it.
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";
}
}
There are several solutions to this problem:
Use an data structure external to the Thread. Pass the object in your constructor and update it, when your Thread is about to finish.
Use a callback method. When your Thread finishes, call the callback.
Make use of a java.util.concurrent.Future
(Java >= 1.5):
A Future represents the result of an asynchronous computation. Methods are provided to check if the computation is complete, to wait for its completion, and to retrieve the result of the computation.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With