2015-06-13 20 views
7

Mam wątku, który ma tylko pracować, gdy pewna okoliczność przychodzi inaczej to po prostu iteracje nad pustym nieskończonej pętli.Java wydajność nieskończona pętla

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

to wpływa na wydajność, gdy pętla faktycznie robi nic, ale musi sprawdzić, czy musi wykonywać obliczenia w każdej iteracji? Tworzenie tego wątku tylko w razie potrzeby nie jest dla mnie opcją, ponieważ moja klasa, która implementuje Runnable, jest wizualnym obiektem, który jest cały czas pokazywany.

edycja: czy poniższe rozwiązanie jest dobre? A może lepiej zastosować inną metodę (dotyczącą wydajności)?

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

Użyj "BlockingQueue"; ta nieskończona pętla pochłonie cały czas procesora. – twentylemon

+1

Nie ma okoliczności, w których ten wątek nie działa. To zawsze działa. –

+1

Czy twój komputer ma zapasowy procesor? Jeśli masz wystarczającą liczbę procesorów, nieprzerwany wątek jest tani. Jeśli nie, to cię to kosztuje. –

Odpowiedz

7

Być może warto rozważyć umieszczenie wątku w trybie uśpienia i budzenie go tylko wtedy, gdy zmienna "kulowa" staje się prawdziwa. Jest na to wiele sposobów, od użycia bardzo niskiego poziomu, wait i notify do korzystania z klas java.util.concurrent, które zapewniają mniej podatny na błędy sposób na zrobienie tego. Zapoznaj się z dokumentacją interfejsu condition. Struktura danych, taka jak BlockingQueue, również byłaby rozwiązaniem.

2

Tak, z pewnością wpłynie to na wydajność. Aby zwiększyć wydajność, możesz rozważyć wprowadzenie pewnego opóźnienia (np. 500ms lub 1000ms lub więcej) w kodzie, w zależności od tego, jak ważny jest dla ciebie czas.

3

Udostępnianie BlockingQueue między wątkami.

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

Tak jest. Jest to najprostsza implementacja busy waiting i należy jej unikać, gdy tylko jest to możliwe. Użyj mechanizmów wait/notify lub java.util.concurrent. Być może powinieneś dokładniej określić, co dokładnie chcesz osiągnąć, aby uzyskać bardziej przydatne odpowiedzi.

Powiązane problemy