2011-05-27 13 views
6

Digamos que quiero crear un objeto que básicamente ejecute un hilo infinitamente. Quiero que el hilo duerma mientras no lo necesite, pero cuando hay una necesidad de hacer cierto trabajo, despierta el hilo: hace el trabajo y vuelve a dormir. También quiero que los trabajos se pongan en cola y se ejecuten en el orden en que llegan. En cacao/objetivo c hay un NSOperationQueue para eso. Me pregunto si Java tiene algo similar.Java: ¿Cómo se puede activar el hilo a pedido?

¿Qué opinas?

Respuesta

3

me gustaría utilizar un ExecutorService como

private final ExecutorService executor = Executors.newSingleThreadExecutor(); 

public void task(final int arg) { 
    executor.execute(new Runnable() { 
     @Override 
     public void run() { 
      // perform task using `arg` 
     } 
    }); 
} 

Esto ha incorporado un hilo que se despierta cuando se añade una tareas y duerme cuando no hay tareas a la izquierda, una cola de bloqueo para las tareas de colas .

2

Puede usar algunos BlockingQueue.

Cuando lee desde la cola (en el hilo), o bien obtiene el siguiente artículo, o si está vacío - espere hasta que se reciba uno.

Esto no está realmente durmiendo el hilo, pero usando la propiedad de bloqueo de la cola. Por ejemplo:

private BlockingQueue queue; 
@Override 
public void run() { 
    while(true) { 
     handle(queue.poll()); 
    } 
} 

El código anterior se encuentra en una Runnable - Se puede usar un ExecutorService para iniciar un ejecutable, o la antigua usanza con una Thread

El qeueue por supuesto está impuesta externamente, y se llena (de nuevo externamente) con los elementos entrantes.

3

Creo que una combinación de BlockingQueue y ThreadPoolExecutor hará lo que necesite.

O, si implementa en un servidor de aplicaciones Java EE, podría usar JMS y un bean controlado por mensajes.

0

Como desea algo similar a la NSOperationQueue, en segundo lugar voy con el ExecutorService de Java. No estoy seguro de si ExecutorService sondea o espera una interrupción. Si necesita más control, hay enfoques impulsados ​​por interrupciones de nivel más bajo, a lo largo de estas líneas:

class InterruptDriven { 
    private final ReentrantLock lock = new ReentrantLock(true); 
    private final Condition asynchronousTrigger = lock.newCondition(); 
    private AtomicBoolean poisoned = new AtomicBoolean(false); 

    public void interrupt() { 
     final ReentrantLock lock = this.lock; 
     try { 
     lock.lockInterruptibly(); 
     asynchronousTrigger.signal(); 
     } catch (InterruptedException ex) { 
     .... 
     } finally { 
     lock.unlock(); 
     } 
    } 
    public void workerWait(){ 
     final ReentrantLock lock = this.lock; 
     lock.lockInterruptibly(); 
     try { 
     try { 
      if (!poisoned.get()) { 
       asynchronousTrigger.await(); 
       ... do some work here ... 
      } 
     } catch (InterruptedException ie) { 
      ... 
     } 
     } finally { 
     lock.unlock(); 
     } 
    } 
Cuestiones relacionadas