Nehmen wir an, ich habe eine Methode doWork(). Wie rufe ich es von einem separaten Thread auf (nicht vom Haupt-Thread)?
Nehmen wir an, ich habe eine Methode doWork(). Wie rufe ich es von einem separaten Thread auf (nicht vom Haupt-Thread)?
Antworten:
Erstellen Sie eine Klasse, die die RunnableSchnittstelle implementiert . Fügen Sie den Code, den Sie ausführen möchten, in die run()Methode ein - das ist die Methode, die Sie schreiben müssen, um der RunnableSchnittstelle zu entsprechen . Erstellen Sie in Ihrem "Haupt" -Thread eine neue ThreadKlasse, übergeben Sie dem Konstruktor eine Instanz von Ihnen Runnableund rufen Sie start()sie dann auf. startWeist die JVM an, die Magie auszuführen, um einen neuen Thread zu erstellen, und dann Ihre runMethode in diesem neuen Thread aufzurufen .
public class MyRunnable implements Runnable {
private int var;
public MyRunnable(int var) {
this.var = var;
}
public void run() {
// code in the other thread, can reference "var" variable
}
}
public class MainThreadClass {
public static void main(String args[]) {
MyRunnable myRunnable = new MyRunnable(10);
Thread t = new Thread(myRunnable)
t.start();
}
}
Schauen Sie sich das Parallelitäts-Tutorial von Java an, um loszulegen.
Wenn Ihre Methode häufig aufgerufen wird, lohnt es sich möglicherweise nicht, jedes Mal einen neuen Thread zu erstellen, da dies eine teure Operation ist. Es wäre wahrscheinlich am besten, einen Thread-Pool zu verwenden. Werfen Sie einen Blick auf Future, Callable, ExecutorKlassen im java.util.concurrentPaket.
run()Methode akzeptiert keine Parameter, daher können Sie dort keine Variable übergeben. Ich würde vorschlagen, dass Sie es im Konstruktor übergeben - ich werde meine Antwort bearbeiten, um das zu zeigen.
new Thread() { public void run() {myMethod();}}.start();Weg, ist das der kürzeste?
Runnable- meine ist eine Klasse, die erweitert wird Runnable. Und weil ich das getan habe, habe ich meinen eigenen Konstruktor, der den Zustand an das instanziierte Objekt übergibt.
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
// code goes here.
}
});
t1.start();
oder
new Thread(new Runnable() {
@Override
public void run() {
// code goes here.
}
}).start();
oder
new Thread(() -> {
// code goes here.
}).start();
oder
Executors.newSingleThreadExecutor().execute(new Runnable() {
@Override
public void run() {
myCustomMethod();
}
});
oder
Executors.newCachedThreadPool().execute(new Runnable() {
@Override
public void run() {
myCustomMethod();
}
});
run()?
In Java 8 können Sie dies mit einer Codezeile tun.
Wenn Ihre Methode keine Parameter akzeptiert, können Sie eine Methodenreferenz verwenden:
new Thread(MyClass::doWork).start();
Andernfalls können Sie die Methode in einem Lambda-Ausdruck aufrufen:
new Thread(() -> doWork(someParam)).start();
->?
Celery task queueasynchrone Dinge verwenden würden
Eine andere schnellere Option zum Aufrufen von Dingen (wie DialogBoxen und MessageBoxen und Erstellen separater Threads für nicht threadsichere Methoden) wäre die Verwendung des Lamba-Ausdrucks
new Thread(() -> {
"code here"
}).start();
Vor einiger Zeit hatte ich eine einfache Dienstprogrammklasse geschrieben, die den JDK5-Executor-Service verwendet und bestimmte Prozesse im Hintergrund ausführt. Da doWork () normalerweise einen ungültigen Rückgabewert hat, möchten Sie diese Dienstprogrammklasse möglicherweise verwenden, um sie im Hintergrund auszuführen.
Siehe diesen Artikel, in dem ich dieses Dienstprogramm dokumentiert hatte.
Um dies mit RxJava 2.x zu erreichen, können Sie Folgendes verwenden:
Completable.fromAction(this::dowork).subscribeOn(Schedulers.io().subscribe();
Die subscribeOn()Methode gibt an, auf welchem Scheduler die Aktion ausgeführt werden soll. RxJava verfügt über mehrere vordefinierte Scheduler, darunter Schedulers.io()einen Thread-Pool für E / A-Vorgänge und Schedulers.computation()einen für CPU-intensive Vorgänge.
Wenn Sie mindestens Java 8 verwenden, können Sie eine Methode runAsyncaus der Klasse CompletableFuture verwenden
CompletableFuture.runAsync(() -> {...});
Wenn Sie ein Ergebnis zurückgeben müssen, verwenden Sie supplyAsyncstattdessen
CompletableFuture.supplyAsync(() -> 1);