2010-02-19 15 views
8

Objekt in Fadenlauf Methode helfen Rückkehr ich eine Java-Klasse, die Thread erstreckt, sieht es im Grunde wie folgt aus:Benötigen

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() { 
     ... 
    } 
} 

Ich brauche die run() Methode ein ByteArrayOutputStream oder ein String zurückzukehren. Da es sich jedoch in der run()-Methode der Thread befindet, kann ich den Rückgabetyp der Methode nicht auf ByteArrayOutputStream oder String festlegen. Die Klasse HttpRequestDispatcher wird innerhalb einer Klasse namens OAuth.java aufgerufen.

Wie kann ich diese Situation umgehen?

Antwort

8

Es gibt mehrere Lösungen für dieses Problem:

  • externen eine Datenstruktur Verwenden Sie zum Thema. Übergeben Sie das Objekt in Ihrem Konstruktor und aktualisieren Sie es, wenn der Thread kurz vor dem Abschluss steht.

  • Verwenden Sie eine Rückrufmethode. Wenn Ihr Thread fertig ist, rufen Sie den Rückruf an.

  • Verwenden Sie eine java.util.concurrent.Future (Java> = 1.5):

    Eine Zukunft das Ergebnis einer asynchronen Berechnung darstellt. Es werden Methoden bereitgestellt, um zu überprüfen, ob die Berechnung abgeschlossen ist, auf ihre Beendigung zu warten und das Ergebnis der Berechnung abzurufen.

+0

Mit der Callback-Methode Ansatz: Der Thread wird beendet, wenn der HttpRequest erfolgreich ist oder fehlschlägt. Nehmen wir an, ich habe zwei Methoden: requestSucceeded und requestFailed. Der Thread ruft je nach Ergebnis eine dieser Methoden auf. Meine eine Frage von dort ist, wie kann ich die Ergebnisse von requestSucceeded oder requestFailed zurück zu der ursprünglichen Methode in OAuth.java, die ursprünglich den Thread? Vielen Dank! – littleK

+0

Sie könnten z. B. Ihre Rückrufe in OAuth.java definieren. Übergeben Sie das OAuth-Objekt an den Thread. Rufen Sie dann je nach Ergebnis den entsprechenden Callback an. Die Callback-Funktion kann "den Absender" als einen der Parameter akzeptieren, wenn Sie mehrere Threads an verschiedene Aktionen senden müssen. Das ist nur eine Idee .. – miku

7

es Callable<T> statt Thread oder Runnable Lassen Sie implementieren. Hier muss T den Typ des Ergebnisses darstellen. Verwenden Sie ExecutorService, um es auszuführen. Es wird das Ergebnis im Geschmack eines Future<V> zurückgeben.

Hier ist ein SSCCE mit String als T, nur copy'n'paste'n'run es.

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"; 
    } 
} 
+0

Ich plane, diesen Ansatz auszuprobieren. Wenn Sie sich meinen Kommentar zum folgenden Beitrag ansehen, werden Sie sehen, dass es zwei Fälle gibt, in denen der Thread endet ... es wird gelingen und einen ByteArrayOutputStream zurückgeben, oder es wird fehlschlagen und einen Stream zurückgeben. Ist das eine gute Methode, verschiedene Arten von Objekten zu akzeptieren? Ich bin auf der Suche nach Vielseitigkeit - es wird viele verschiedene Klassen geben mit diesem HttpRequestDispatcher – littleK

+0

Machen Sie es abstrakt und nennen Sie es "HttpResponse". Es wird einfacher werden. – BalusC