thread - runnable java example
Java Runnable run() método devuelve un valor (8)
De acuerdo con el documento de Java, el método Runnable
void run()
no puede devolver un valor. Sin embargo, me pregunto si hay alguna solución de esto.
En realidad, tengo un método que llama:
public class Endpoint{
public method_(){
RunnableClass runcls = new RunnableClass();
runcls.run()
}
}
wheren method run()
es:
public class RunnableClass implements Runnable{
public jaxbResponse response;
public void run() {
int id;
id =inputProxy.input(chain);
response = outputProxy.input();
}
}
Quiero tener acceso a la variable de response
en method_()
es esto posible?
Echa un vistazo a la clase Callable . Esto generalmente se envía a través de un servicio de ejecutor
Puede devolver un objeto futuro que se devuelve cuando finaliza el hilo
Eche un vistazo a la interfaz invocable , quizás esta suite satisfaga sus necesidades. También puede intentar obtener el valor del campo de respuesta llamando a un método setter dentro de su método run()
public void run() {
int id;
id =inputProxy.input(chain);
response = outputProxy.input();
OuterClass.setResponseData(response);
}
Pruebe lo siguiente
public abstract class ReturnRunnable<T> implements Runnable {
public abstract T runForResult();
@Override
public void run() {
runForResult();
}
}
Sí, hay una solución. Simplemente use la cola y ponga en ella el valor que desea devolver. Y toma este valor de otro hilo.
public class RunnableClass implements Runnable{
private final BlockingQueue<jaxbResponse> queue;
public RunnableClass(BlockingQueue<jaxbResponse> queue) {
this.queue = queue;
}
public void run() {
int id;
id =inputProxy.input(chain);
queue.put(outputProxy.input());
}
}
public class Endpoint{
public method_(){
BlockingQueue<jaxbResponse> queue = new LinkedBlockingQueue<>();
RunnableClass runcls = new RunnableClass(queue);
runcls.run()
jaxbResponse response = queue.take(); // waits until takes value from queue
}
}
Si agrega un campo a RunnableClass
, puede configurarlo en run
y leerlo en method_
. Sin embargo, Runnable
es una interface
pobre (la palabra clave Java) ya que no le dice nada sobre la interfaz (el concepto) (solo la línea útil de los documentos API: "El contrato general del método run
es que puede tomar cualquier medida. "). Es mucho mejor usar una interfaz más significativa (que puede devolver algo).
Una forma es, tenemos que usar el enfoque Future - Callable
.
Otra forma es, en lugar de devolver el valor, puede mantener el objeto
Ejemplo:
class MainThread {
public void startMyThread() {
Object requiredObject = new Object(); //Map/List/OwnClass
Thread myThread = new Thread(new RunnableObject(requiredObject)).start();
myThread.join();
System.out.println(requiredObject.getRequiredValue());
}
}
class RunnableObject implements Runnable {
private Object requiredObject;
public RunnableObject(Object requiredObject) {
this.requiredObject = requiredObject;
}
public void run() {
requiredObject.setRequiredValue(xxxxx);
}
}
Debido a que el alcance del objeto está en el mismo ámbito, de modo que puede pasar el objeto al hilo y puede recuperarlo en el ámbito principal. Pero, lo más importante es que tenemos que usar el método join (). Debido a que el alcance principal debería estar esperando la finalización del hilo de su tarea.
Para el caso de múltiples hilos, puede usar List
/ Map
para mantener los valores de los hilos.
Use Callable<V>
lugar de usar la interfaz Runnable
.
Ejemplo:
public static void main(String args[]) throws Exception {
ExecutorService pool = Executors.newFixedThreadPool(3);
Set<Future<Integer>> set = new HashSet<Future<Integer>>();
for (String word: args) {
Callable<Integer> callable = new WordLengthCallable(word);
Future<Integer> future = pool.submit(callable);
set.add(future);
}
int sum = 0;
for (Future<Integer> future : set) {
sum += future.get();
}
System.out.printf("The sum of lengths is %s%n", sum);
System.exit(sum);
}
En este ejemplo, también necesitará implementar la clase WordLengthCallable, que implementa la interfaz de llamada.
public void check() {
ExecutorService executor = Executors.newSingleThreadExecutor();
Future<Integer> result = executor.submit(new Callable<Integer>() {
public Integer call() throws Exception {
return 10;
}
});
try {
int returnValue = result.get();
} catch (Exception exception) {
//handle exception
}
}