Нужна помощь в возврате объекта в методе потока - PullRequest
9 голосов
/ 20 февраля 2010

У меня есть класс 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(), чтобы вернуть ByteArrayOutputStream или String. Однако, поскольку он используется в методе run() из Thread, я не могу установить тип возвращаемого значения для метода ByteArrayOutputStream или String.

Класс HttpRequestDispatcher вызывается внутри класса с именем OAuth.java.

Как мне обойти эту ситуацию?

Ответы [ 2 ]

9 голосов
/ 20 февраля 2010

Существует несколько решений этой проблемы:

  • Использовать структуру данных, внешнюю по отношению к потоку.Передайте объект в ваш конструктор и обновите его, когда ваш поток собирается закончить.

  • Используйте метод обратного вызова.Когда ваш поток завершится, вызовите обратный вызов.

  • Используйте java.util.concurrent.Future (Java> = 1,5):

    Будущее представляет собой результат асинхронных вычислений.Предоставляются методы для проверки того, завершено ли вычисление, для ожидания его завершения и для извлечения результата вычисления.

7 голосов
/ 20 февраля 2010

Позвольте ему реализовать Callable<T> вместо Thread или Runnable. Здесь T должен представлять тип результата. Используйте ExecutorService для его выполнения. Он вернет результат в виде Future<V>.

Вот 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";
    }
}
...