2015-06-13 19 views
7

Ho un filo che deve solo lavorare quando una certa circostanza viene in caso contrario esso diventa subito itera su un ciclo infinito vuoto:.Java prestazioni loop infinito

public void run() { 
    while(true) { 
     if(ball != null) { 
      // do some Calculations 
     } 
    } 
} 

influisce le prestazioni quando il loop realmente fa niente ma deve controllare se deve fare il calcolo ogni iterazione? Solo la creazione di questo thread quando necessario non è un'opzione per me, perché la mia classe che implementa Runnable è un oggetto visivo che è sempre mostrato.

modifica: la seguente è una buona soluzione? O è meglio usare un metodo diverso (relativo alle prestazioni)?

private final Object standBy = new Object(); 

public void run() { 
    while(true) { 
     synchronized (standBy) { 
      while(ball != null) // should I use while or if here? 
       try{ standBy.wait() } 
       catch (InterruptedException ie) {} 
     } 
     if(ball != null) { 
      // do some Calculations 
     } 
} 

public void handleCollision(Ball b) { 
    // some more code.. 
    ball = b; 
    synchronized (standBy) { 
     standBy.notify(); 
    } 
} 
+2

Utilizzare un 'BlockingQueue'; questo ciclo infinito mangerà tutto il tempo della CPU. – twentylemon

+1

Non c'è alcuna circostanza in cui questo thread non funzioni. Fa sempre del lavoro. –

+1

Il computer dispone di un processore di riserva? Se disponi di processori sufficienti, un thread a esecuzione continua è economico. In caso contrario, ti costa. –

risposta

7

Si consiglia di considerare di sospendere il thread e di riattivarlo solo quando la variabile "ball" diventa vera. Esistono diversi modi per eseguire questa operazione, dall'utilizzo delle istruzioni a livello molto basso, wait e notify all'utilizzo delle classi java.util.concurrent che forniscono un modo meno incline a farlo. Dai un'occhiata alla documentazione per l'interfaccia condition. Una struttura dati come una BlockingQueue sarebbe anche una soluzione.

2

Sì, influirà sicuramente sulle prestazioni. Per aumentare le prestazioni, puoi considerare di inserire un po 'di tempo nel tuo codice (diciamo 500ms o 1000ms o anche più alto) a seconda di quanto sia cruciale il tempismo per te.

3

Condividi un BlockingQueue tra le tue discussioni.

class Producer implements Runnable { 
    private final BlockingQueue queue; 
    Producer(BlockingQueue q) { queue = q; } 
    public void run() { 
    try { 
     while (true) { queue.put(produce()); } 
    } catch (InterruptedException ex) { ... handle ...} 
    } 
    Object produce() { ... } 
} 

class Consumer implements Runnable { 
    private final BlockingQueue queue; 
    Consumer(BlockingQueue q) { queue = q; } 
    public void run() { 
    try { 
     while (true) { consume(queue.take()); } 
    } catch (InterruptedException ex) { ... handle ...} 
    } 
    void consume(Object x) { ... } 
} 
7

Sì, sì. Questa è l'implementazione più semplice di busy waiting e dovrebbe essere evitata quando possibile. Utilizzare i meccanismi wait/notify o java.util.concurrent. Forse dovresti essere più specifico su cosa esattamente vuoi ottenere per ottenere risposte più utili.