Digamos que tengo un método doWork()
. ¿Cómo lo llamo desde un hilo separado (no el hilo principal)?
Digamos que tengo un método doWork()
. ¿Cómo lo llamo desde un hilo separado (no el hilo principal)?
Respuestas:
Cree una clase que implemente la Runnable
interfaz. Coloque el código que desea ejecutar en el run()
método; ese es el método que debe escribir para cumplir con la Runnable
interfaz. En su hilo "principal", cree una nueva Thread
clase, pasando al constructor una instancia de su Runnable
, luego invoque start()
. start
le dice a la JVM que haga la magia para crear un nuevo hilo, y luego llame a su run
método en ese nuevo hilo.
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();
}
}
Eche un vistazo al tutorial de concurrencia de Java para comenzar.
Si su método se va a llamar con frecuencia, entonces puede que no valga la pena crear un nuevo hilo cada vez, ya que esta es una operación costosa. Probablemente sería mejor usar un grupo de subprocesos de algún tipo. Echar un vistazo a Future
, Callable
, Executor
clases en el java.util.concurrent
paquete.
run()
método no toma parámetros, por lo que no puede pasar una variable allí. Te sugiero que lo pases en el constructor. Editaré mi respuesta para mostrar eso.
new Thread() { public void run() {myMethod();}}.start();
camino, ¿es el más corto?
Runnable
: la mía es una clase que se extiende Runnable
. Y como he hecho eso, tengo mi propio constructor que pasa el estado al objeto instanciado.
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()
?
En Java 8 puede hacer esto con una línea de código.
Si su método no toma ningún parámetro, puede usar una referencia de método:
new Thread(MyClass::doWork).start();
De lo contrario, puede llamar al método en una expresión lambda:
new Thread(() -> doWork(someParam)).start();
->
?
Celery task queue
Otra opción más rápida para llamar a cosas (como DialogBoxes y MessageBoxes y crear subprocesos separados para métodos que no sean seguros para subprocesos) sería usar Lamba Expression
new Thread(() -> {
"code here"
}).start();
Hace algún tiempo, había escrito una clase de utilidad simple que usa el servicio de ejecución JDK5 y ejecuta procesos específicos en segundo plano. Como doWork () normalmente tendría un valor de retorno nulo, es posible que desee utilizar esta clase de utilidad para ejecutarla en segundo plano.
Vea este artículo donde había documentado esta utilidad.
Para lograr esto con RxJava 2.x puede usar:
Completable.fromAction(this::dowork).subscribeOn(Schedulers.io().subscribe();
El subscribeOn()
método especifica en qué planificador ejecutar la acción: RxJava tiene varios planificadores predefinidos, incluido el Schedulers.io()
que tiene un grupo de subprocesos destinado a operaciones de E / S y el Schedulers.computation()
que está destinado a operaciones intensivas de CPU.
Si está utilizando al menos Java 8, puede usar el método runAsync
de la clase CompletableFuture
CompletableFuture.runAsync(() -> {...});
Si necesita devolver un resultado, use supplyAsync
en su lugar
CompletableFuture.supplyAsync(() -> 1);