У меня есть класс Java, который расширяется Thread
, это в основном похоже на следующее:
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()
метод для возврата a ByteArrayOutputStream
или a String
. Однако, потому что это находится в run()
метод Thread
, Я не могу установить тип возврата метода к a ByteArrayOutputStream
или a String
.
HttpRequestDispatcher
класс называют в классе под названием OAuth.java.
Как я могу обойти эту ситуацию?
Есть несколько решений этой проблемы:
Используйте структуру данных, внешнюю по отношению к потоку. Передайте объект в конструктор и обновляйте его, когда ваш поток будет завершен.
Использовать метод обратного вызова. Когда ваш поток завершится, вызовите обратный вызов.
Используйте java.util.concurrent.Future
(Java >= 1.5):
Future представляет результат асинхронного вычисления. Предусмотрены методы для проверки завершения вычисления, ожидания его завершения и получения результата вычисления.
Пусть он реализует Callable
вместо Thread
или Runnable
. Здесь T
должен представлять тип результата. Используйте ExecutorService
для его выполнения. Он вернет результат в виде Future
.
Вот SSCCE с String
в качестве T
, просто скопируйте, вставьте и запустите его.
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";
}
}