ejemplos - java executorservice example
Java: parametrizado ejecutable (6)
La interfaz estándar de Runnable
solo tiene el método run()
no parametrizado. También hay una Callable<V>
con el método call()
que devuelve el resultado de un tipo genérico. Necesito pasar un parámetro genérico, algo como esto:
¿Hay alguna interfaz estándar para este propósito o debo declarar esa básica por mí mismo? interface MyRunnable<E> {
public abstract void run(E reference);
}
Generalmente, si desea pasar un parámetro al método run()
, se subclase Runnable
con un constructor que toma un parámetro.
Por ejemplo, quieres hacer esto:
// code
Runnable r = new YourRunnable();
r.run(someParam);
//more code
Usted necesita hacer ésto:
// code
Runnable r = new YourRunnable(someParam);
r.run();
//more code
Va a implementar YourRunnable
similar a continuación:
public class YourRunnable implements Runnable {
Some param;
public YourRunnable(Some param){
this.param = param;
}
public void run(){
// do something with param
}
}
Java 8 incluye la interfaz java.util.function.Consumer<T>
con el único método de no void accept(T t)
por defecto void accept(T t)
.
Hay muchas otras interfaces relacionadas en ese paquete .
Por lo general, implementaría Runnable
o Callable
como una clase que admite un parámetro de entrada genérico; p.ej
public class MyRunnable<T> implements Runnable {
private final T t;
public MyRunnable(T t) {
this.t = t;
}
public void run() {
// Reference t.
}
}
Runnable no debe ser llamado directamente por el código del cliente como foo.run()
que se ejecutaría secuencialmente en el hilo actual.
Desde la API de Runnable :
La interfaz Runnable debe ser implementada por cualquier clase cuyas instancias estén destinadas a ser ejecutadas por un hilo. La clase debe definir un método sin argumentos llamado run.
Esta interfaz está diseñada para proporcionar un protocolo común para los objetos que desean ejecutar código mientras están activos. Por ejemplo, Runnable es implementado por la clase Thread. Estar activo simplemente significa que un hilo se ha iniciado y aún no se ha detenido.
Además, Runnable proporciona los medios para que una clase esté activa sin subclasificar Thread. Una clase que implementa Runnable puede ejecutarse sin subclasificar Thread creando una instancia de Thread y pasándose a sí misma como destino. En la mayoría de los casos, la interfaz de Runnable debe usarse si solo planea anular el método run () y ningún otro método Thread. Esto es importante porque las clases no deben clasificarse a menos que el programador intente modificar o mejorar el comportamiento fundamental de la clase.
En su lugar, crea una nueva instancia de Thread basada en su ejecutable, y luego llama a bar.start()
. Entonces es responsabilidad de la JVM llamar a run()
en este hilo separado.
Ejemplo:
public class Foo<E> implements Runnable {
private final E e;
public Foo(E e) { ... }
@Override
public void run() {
do something with e.
}
}
Foo<String> foo = new Foo("hello");
Thread bar = new Thread(foo);
bar.start();
Sugiero definir una interfaz como se hace en la pregunta original. Además, evite la escritura débil haciendo que la interfaz sea específica para lo que se supone que debe hacer, en lugar de una interfaz sin sentido como Runnable
.
También hay com.google.common.base.Function<F, T>
de Google Collections Guava .
Si establece el tipo de salida a ?
o Void
(y siempre que se devuelva null
) puede usarlo como una alternativa a Runnable
con un parámetro de entrada.
Esto tiene la ventaja de poder utilizar Functions.compose
para transformar el valor de entrada, Iterables.transform
para aplicarlo a cada elemento de una colección, etc.