thread practice how example creating create concurrent java multithreading concurrency synchronization

java - practice - Ejecutando código en el hilo principal de un hilo secundario?



java concurrency in practice (5)

En caso de que estés en Android, ¿usar un Handler debería hacer el trabajo?

new Handler(Looper.getMainLooper()).post(new Runnable () { @Override public void run () { ... } });

¡Esta es una pregunta general de Java y no una de Android!

Me gustaría saber cómo ejecutar código en el hilo principal, desde el contexto de un hilo secundario. Por ejemplo:

new Thread(new Runnable() { public void run() { //work out pi to 1,000 DP (takes a while!) //print the result on the main thread } }).start();

Ese tipo de cosas, me doy cuenta de que mi ejemplo es un poco deficiente, ya que en Java no es necesario estar en el hilo principal para imprimir algo, y que Swing también tiene una cola de eventos, pero la situación genérica en la que podría ser necesario ejecute run aable en el hilo principal mientras se encuentra en el contexto de un hilo de fondo.

EDITAR: Para comparación, así es como lo haría en Objective-C:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0UL), ^{ //do background thread stuff dispatch_async(dispatch_get_main_queue(), ^{ //update UI }); });

¡Gracias por adelantado!


Es posible que desee utilizar el ''subproceso de distribución uniforme'' donde suceden la mayoría de las cosas basadas en eventos. Si está utilizando swing entonces:

SwingUtilities.invokeLater(new Runnable() { public void run() { Your code here. } });

O cree una clase que implemente Runnable y pásela a invokeLater ().


No hay una forma universal de enviar un código a otro hilo en ejecución y decir "Oye, haz esto". Necesitaría poner el hilo principal en un estado en el que tenga un mecanismo para recibir trabajo y esté a la espera de que se realice el trabajo.

Este es un ejemplo sencillo de cómo configurar el hilo principal para esperar a recibir trabajo de otros hilos y ejecutarlo a medida que llega. ¡Obviamente, usted querría agregar una manera de finalizar realmente el programa y así sucesivamente ...!

public static final BlockingQueue<Runnable> queue = new LinkedBlockingQueue<Runnable>(); public static void main(String[] args) throws Exception { new Thread(new Runnable(){ @Override public void run() { final int result; result = 2+3; queue.add(new Runnable(){ @Override public void run() { System.out.println(result); } }); } }).start(); while(true) { queue.take().run(); } }


Si está utilizando JavaFX, lo cual recomiendo ampliamente, entonces puede usar

Platform.runLater(new Runnable() { @Override public void run() { alert(text); } });

desde dentro de su subproceso que no es de la interfaz de usuario, y Runnable se ejecutará desde el subproceso de la interfaz de usuario al regresar de su hilo.


Una discusión antigua, pero si se trata de enviar una solicitud al hilo principal (no en la dirección opuesta) también puede hacerlo con futuros. El objetivo básico es ejecutar algo en segundo plano y, cuando finalice, obtener el resultado:

public static void main(String[] args) throws InterruptedException, ExecutionException { // create the task to execute System.out.println("Main: Run thread"); FutureTask<Integer> task = new FutureTask<Integer>( new Callable<Integer>() { @Override public Integer call() throws Exception { // indicate the beginning of the thread System.out.println("Thread: Start"); // decide a timeout between 1 and 5s int timeout = 1000 + new Random().nextInt(4000); // wait the timeout Thread.sleep(timeout); // indicate the end of the thread System.out.println("Thread: Stop after " + timeout + "ms"); // return the result of the background execution return timeout; } }); new Thread(task).start(); // here the thread is running in background // during this time we do something else System.out.println("Main: Start to work on other things..."); Thread.sleep(2000); System.out.println("Main: I have done plenty of stuff, but now I need the result of my function!"); // wait for the thread to finish if necessary and retrieve the result. Integer result = task.get(); // now we can go ahead and use the result System.out.println("Main: Thread has returned " + result); // you can also check task.isDone() before to call task.get() to know // if it is finished and do somethings else if it is not the case. }

Si su intención es hacer varias cosas en segundo plano y recuperar los resultados, puede establecer algunas colas como se dijo anteriormente o puede dividir el proceso en varios futuros (comenzando de una vez o comenzando una nueva cuando sea necesario, incluso desde otro futuro) . Si almacena cada tarea en un mapa o una lista, inicializada en el hilo principal, puede verificar los futuros que desee en cualquier momento y obtener sus resultados cuando hayan terminado.