Mam pętlę główną w wątku, a jego część sprawdza, czy wartość boolean bezczynności jest prawdziwa. Jeśli tak, zadzwoni pod numer Thread.sleep(1)
po każdej iteracji pętli. Czy jest to skuteczny sposób na zrobienie tego? Moim celem jest, aby wątek zużył minimalne użycie procesora, gdy jest bezczynny.Czy w Javie można używać Thread.sleep (1) do wątku bezczynności?
Odpowiedz
Zamiast tego należy użyć Object.wait
i upewnić się, że synchronizowano obiekt zawierający wartość logiczną. Jeśli nie dokonasz synchronizacji, a boolean
nie jest volatile
, nie masz żadnej bariery pamięci, więc nie ma gwarancji, że wątek odpytywania zobaczy zmianę na boolean
.
Według javadoc:
Metoda ta powoduje bieżącego wątku (nazwać T), aby umieścić się w zestawie oczekiwania dla tego obiektu i do oddania wszelkie żądania synchronizacji tego obiektu. Temat T staje wyłączone dla celów planowania wątek i drzemie dopóki jeden z czterech rzeczy dzieje:
- Jakiś inny wątek wywołuje metodę
notify
dla tego obiektu i nici T dzieje się dowolnie wybrany wątek, aby być budzony .- Inny wątek wywołuje metodę
notifyAll
dla tego obiektu.- Jakiś inny wątek przerywa wątek T.
- ...
więc nitka będzie miała żadnego procesora podczas oczekiwania mają być notyfikowane.
Poniższy kod jest prostą flagą bezczynności z metodą waitUntilIdle
, którą można wywołać metodą main
i metodą setIdle
, którą można wywołać innym wątkiem.
public class IdleFlag {
private boolean idle;
public void waitUntilIdle() throws InterruptedException {
synchronized (this) {
while (true) {
// If the flag is set, we're done.
if (this.idle) { break; }
// Go to sleep until another thread notifies us.
this.wait();
}
}
}
public void setIdle() {
synchronized (this) {
this.idle = true;
// Causes all waiters to wake up.
this.notifyAll();
}
}
}
Chociaż to zadziała, jaki jest powód 'while (true)' poza synchronizacją? Po prostu zwolni blokadę i ponownie zacznie działać po odczekaniu (a następnie zwolnieniu). Zgodnie z określeniem 'while (true)' w synchronizacji, uzyskaj/zwolnij semantykę (tylko raz) za każdym razem, gdy oczekiwane jest powiadomienie (regularnie lub fałszywie). –
Cóż, myślę, że moim celem jest, abyś mógł po prostu 'while' w synchronizacji, w której nie musiałbyś wydać dodatkowego wydania/zdobyć, robiąc to na zewnątrz. Masz rację, nie wyrządza żadnej szkody funkcjonalnej, a wpływ na wydajność jest prawdopodobnie znikomy. –
@JohnVint, dobry punkt. Edytowane. –
zgadzam się z @Mike Samuela, jeszcze chciałbym zalecić użyć concurrent lock packages...
Kontynuuj paradygmatu Mike'a prostu wymienić swój zamek, który wprowadził w Javie 5
Dokładniej ty mogą korzystać z metod oczekujących na metody - te, które mają limity czasowe. W ten sposób możesz, na przykład, rejestrować wiadomość co jakiś czas - wiadomość, która pomoże ci zdebugować nieskończone oczekiwania. Możesz także chcieć wykonać logikę wycofywania, jeśli oczekiwanie na timeout ...
Istnieje wersja 'wait', która wymaga limitu czasu, więc jeśli chcesz, aby czas procesora był tak często rejestrowany, użycie' 'wait (timeout)' jest łatwiejsze niż wprowadzenie 'Condition's. –
@John Haager - dziękuję za wgląd, wstydzę się powiedzieć, że nie wiedziałem o tym – Yaneeve
Wciąż - warunki są związane z Blokadami, i pozwalają ci robić bardziej interesujące rzeczy niż proste synchronizacje – Yaneeve
- 1. Czy Thread.Sleep (1) jest wyjątkowe?
- 2. Czy można bezpiecznie używać funkcji SHFileOperation w wątku roboczym?
- 3. Zatrzymywanie wątku w Javie?
- 4. Czy można zadeklarować zmienną 1-bitową w Javie?
- 5. Jak poprawnie uzyskać nazwę wątku w Javie?
- 6. Asynchronous Thread.Sleep()
- 7. Czy można używać wątku Qt bez dziedziczenia jakiegokolwiek obiektu Qt?
- 8. Thread.sleep() w pętli while
- 9. Jaki jest odpowiednik Java's Thread.sleep() w Objective-C/Cocoa?
- 10. Jak używać v8 w wątku?
- 11. Wykorzystanie pamięci wątku lub procesu w Javie
- 12. Thread.Sleep vs Task.Delay?
- 13. Kiedy używać handler.post(), gdy do nowego wątku()
- 14. Ograniczanie użycia procesora/pamięci wątku w Javie?
- 15. Czy można bezpiecznie przechwycić StackOverflowError w Javie?
- 16. Jak używać notifyDataSetChanged() w wątku
- 17. Używanie Thread.Sleep() w usłudze Windows
- 18. jak używać ln w Javie
- 19. Korzystanie Thread.Sleep w Xamarin.Forms
- 20. Czy można używać dziedziczenia w interfejsach AIDL?
- 21. W Javie, czy można trochę wyczyścić?
- 22. Czy można przywołać println w Javie?
- 23. kiedy używać zadania i kiedy używać wątku?
- 24. Detekcja bezczynności w WPF
- 25. Czy kiedykolwiek bezpieczne zawsze ignorować InterruptedException wzywającą sen wątku() w Javie
- 26. Dlaczego ograniczenie GC do 1 wątku zwiększa wydajność?
- 27. Czy startServce() można wywołać z dowolnego wątku?
- 28. Czy można używać GPU do przyspieszania mieszania w Pythonie?
- 29. Kiedy używać "tego" w Javie
- 30. Czy można bezpiecznie używać ReadWriterLockSlim w asynchronicznej metodzie
Czy to nie potrwa, zanim system będzie ciągle wymieniał wątki w ten sposób? To wymaga mocy obliczeniowej, aby menedżer wątków wykonał swoje zadanie, a Ty prosisz o wykonanie tej pracy co milisekundę. – scriptocalypse
Jedna rzecz, którą podejrzewałem, może się zdarzyć, ale nie byłem wtedy pewien. To brzmi jak 'wait' i' notifyAll' wykona zadanie dobrze. – AutoBotAM