Ich habe eine Methode mit a HandlerThread
. Ein Wert wird innerhalb von geändert Thread
und ich möchte ihn an die test()
Methode zurückgeben. Gibt es eine Möglichkeit, dies zu tun?
public void test()
{
Thread uiThread = new HandlerThread("UIHandler"){
public synchronized void run(){
int value;
value = 2; //To be returned to test()
}
};
uiThread.start();
}
java
android
multithreading
Neeta
quelle
quelle
Antworten:
Sie können ein lokales endgültiges Variablenarray verwenden. Die Variable muss nicht primitiv sein, damit Sie ein Array verwenden können. Sie müssen auch die beiden Threads synchronisieren, z. B. mithilfe eines CountDownLatch :
Sie können auch ein
Executor
und einCallable
solches verwenden:quelle
Normalerweise würden Sie es so etwas tun
Dann können Sie den Thread erstellen und den Wert abrufen (vorausgesetzt, der Wert wurde festgelegt).
tl;dr
Ein Thread kann keinen Wert zurückgeben (zumindest nicht ohne Rückrufmechanismus). Sie sollten einen Thread wie eine normale Klasse referenzieren und nach dem Wert fragen.quelle
The method getValue() is undefined for the type Thread
.t.getValue()
zufoo.getValue()
.Thread t = new Thread(foo); t.start(); t.join(); foo.getValue();
. Diet.join()
Blöcke bis der Thread fertig ist.Was Sie suchen, ist wahrscheinlich die
Callable<V>
Schnittstelle anstelle vonRunnable
und das Abrufen des Werts mit einemFuture<V>
Objekt, wodurch Sie auch warten können, bis der Wert berechnet wurde. Sie können dies mit einem erreichenExecutorService
, von dem Sie erhalten könnenExecutors.newSingleThreadExecutor()
.quelle
Wie wäre es mit dieser Lösung?
Es verwendet nicht die Thread-Klasse, aber es ist gleichzeitig und in gewisser Weise genau das, was Sie anfordern
Jetzt müssen Sie nur noch sagen,
value.get()
wann immer Sie Ihren zurückgegebenen Wert abrufen müssen. Der Thread wird in der Sekunde gestartet, in der Sievalue
einen Wert angeben, damit Sie nie etwas dazu sagen müssenthreadName.start()
.Was
Future
ist, ist ein Versprechen an das Programm, Sie versprechen dem Programm, dass Sie ihm den Wert geben, den es irgendwann in naher Zukunft benötigtWenn Sie es aufrufen
.get()
, bevor es fertig ist, wartet der Thread, der es aufruft, einfach, bis es fertig istquelle
Wenn Sie den Wert von der aufrufenden Methode erhalten möchten, sollte er warten, bis der Thread beendet ist, was die Verwendung von Threads etwas sinnlos macht.
Um Ihre Frage direkt zu beantworten, kann der Wert in jedem veränderlichen Objekt gespeichert werden, auf das sowohl die aufrufende Methode als auch der Thread verweisen. Sie könnten das Äußere verwenden
this
, aber das wird nur für triviale Beispiele besonders nützlich sein.Ein kleiner Hinweis zum Code in der Frage: Das Erweitern
Thread
ist normalerweise ein schlechter Stil. In der Tat ist es unnötig, Klassen unnötig zu erweitern. Ich stelle fest, dass Ihrerun
Methode aus irgendeinem Grund synchronisiert ist. Da es sich in diesem Fall um das Objekt handeltThread
, können Sie in das eingreifen , wofürThread
die Sperre verwendet wird (in der Referenzimplementierung etwas mitjoin
IIRC zu tun ).quelle
Ab Java 8 haben wir CompletableFuture. In Ihrem Fall können Sie die Methode supplyAsync verwenden , um das Ergebnis nach der Ausführung abzurufen .
Bitte finden Sie einige ref. hier https://www.baeldung.com/java-completablefuture#Processing
quelle
Die Verwendung von Future, wie in den obigen Antworten beschrieben, erledigt den Job, blockiert den Thread jedoch etwas weniger als f.get (), bis er das Ergebnis erhält, das die Parallelität verletzt.
Die beste Lösung ist die Verwendung von ListenableFuture von Guava. Ein Beispiel :
quelle
Mit kleinen Änderungen an Ihrem Code können Sie dies allgemeiner erreichen.
Lösung:
Handler
In-UI-Thread, der als bezeichnet wirdresponseHandler
Handler
ausLooper
dem UI - Thread.HandlerThread
, Post Nachricht auf diesemresponseHandler
handleMessgae
zeigt einenToast
mit dem von der Nachricht empfangenen Wert. Dieses Nachrichtenobjekt ist generisch und Sie können verschiedene Arten von Attributen senden.Mit diesem Ansatz können Sie mehrere Werte zu unterschiedlichen Zeitpunkten an den UI-Thread senden. Sie können viele
Runnable
Objekte auf diesem Objekt ausführen (veröffentlichen)HandlerThread
und jedesRunnable
kann einen Wert imMessage
Objekt festlegen , der vom UI-Thread empfangen werden kann.quelle