diciamo che ho un metodo doWork()
. Come lo chiamo da un thread separato (non il thread principale).
diciamo che ho un metodo doWork()
. Come lo chiamo da un thread separato (non il thread principale).
Risposte:
Crea una classe che implementa l' Runnable
interfaccia. Inserisci il codice che vuoi eseguire nel run()
metodo: questo è il metodo che devi scrivere per essere conforme Runnable
all'interfaccia. Nel tuo thread "principale", crea una nuova Thread
classe, passando al costruttore una tua istanza Runnable
, quindi chiamala start()
. start
dice alla JVM di fare la magia per creare un nuovo thread e quindi chiamare il tuo run
metodo in quel nuovo thread.
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();
}
}
Dai un'occhiata al tutorial sulla concorrenza di Java per iniziare.
Se il tuo metodo verrà chiamato frequentemente, potrebbe non valere la pena creare un nuovo thread ogni volta, poiché si tratta di un'operazione costosa. Probabilmente sarebbe meglio usare un pool di thread di qualche tipo. Date un'occhiata a Future
, Callable
, Executor
classi nel java.util.concurrent
pacchetto.
run()
metodo non accetta parametri, quindi non puoi passare una variabile lì. Suggerirei di passarlo nel costruttore: modificherò la mia risposta per dimostrarlo.
new Thread() { public void run() {myMethod();}}.start();
strada, è la più breve?
Runnable
: la mia è una classe che si estende Runnable
. E poiché l'ho fatto, ho il mio costruttore che passa lo stato nell'oggetto istanziato.
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
// code goes here.
}
});
t1.start();
o
new Thread(new Runnable() {
@Override
public void run() {
// code goes here.
}
}).start();
o
new Thread(() -> {
// code goes here.
}).start();
o
Executors.newSingleThreadExecutor().execute(new Runnable() {
@Override
public void run() {
myCustomMethod();
}
});
o
Executors.newCachedThreadPool().execute(new Runnable() {
@Override
public void run() {
myCustomMethod();
}
});
run()
?
In Java 8 puoi farlo con una riga di codice.
Se il tuo metodo non accetta parametri, puoi utilizzare un metodo di riferimento:
new Thread(MyClass::doWork).start();
Altrimenti, puoi chiamare il metodo in un'espressione lambda:
new Thread(() -> doWork(someParam)).start();
->
?
Celery task queue
Un'altra opzione più rapida per chiamare cose (come DialogBoxes e MessageBoxes e creare thread separati per metodi non thread-safe) sarebbe quella di utilizzare Lamba Expression
new Thread(() -> {
"code here"
}).start();
Qualche tempo fa, avevo scritto una semplice classe di utilità che utilizza il servizio esecutore JDK5 ed esegue processi specifici in background. Poiché doWork () in genere avrebbe un valore di ritorno void, potresti voler utilizzare questa classe di utilità per eseguirlo in background.
Vedi questo articolo in cui avevo documentato questa utility.
Per ottenere ciò con RxJava 2.x puoi utilizzare:
Completable.fromAction(this::dowork).subscribeOn(Schedulers.io().subscribe();
Il subscribeOn()
metodo specifica su quale scheduler eseguire l'azione - RxJava ha diversi scheduler predefiniti, incluso il Schedulers.io()
quale ha un pool di thread destinato alle operazioni di I / O e Schedulers.computation()
che è inteso per le operazioni a uso intensivo della CPU.
Se stai usando almeno Java 8 puoi usare il metodo runAsync
della classe CompletableFuture
CompletableFuture.runAsync(() -> {...});
Se devi restituire un risultato, usa supplyAsync
invece
CompletableFuture.supplyAsync(() -> 1);