Známé problémy a jejich řešení
GUI nereaguje, jak by se čekalo, ve verzi Javy 1.8
Problém se projevuje tím, že GUI programu se zasekne a nereaguje na akci, která měl způsobit pokračování, a toto se navíc děje pouze v případě, že program je spuštěn ve verzi Javy 1.8. Ve verzi 1.7 to jede. Tento problém se objevuje, pokud máte pozastaveno vykonávání kontrolního toku programu pomocí prázdné smyčky:
while (some_variable == SOME_CONST) { }
Příčina
Důvod tohoto chování je objasněn zde https://stackoverflow.com/questions/8409609/java-empty-while-loop
Řešení
Možné řešení je nastíněno ve výše zmíněném odkazu - u proměnných, na jejichž změnu se čeká v prázdném cyklu, použít klíčové slovo volatile. Nicméně čekání pomocí prázdné smyčky je neefektivní a zbytečně zatěžuje procesor. Ideální řešení je čekat pomocí synchronizačních mechanismů wait a notifyAll - detailně to je vysvětleno zde https://docs.oracle.com/javase/tutorial/essential/concurrency/guardmeth.html.
Kód, který má počkat, než se nastaví hodnota proměnné na požadovanou hodnotu vypadá nějak takto:
synchronized (ref_of_monitor) { while (some_variable == SOME_CONST) { try { ref_of_monitor.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } }
Kód, který modifikuje hodnotu testované proměnné (na jiném vlákně), vypadá nějak takto:
synchronized (ref_of_monitor) { some_variable = SOME_CONST; ref_of_monitor.notifyAll(); }
Pokud jste nebyly schopni tuto věc vyřešit výše zmíněným ideálním způsobem, tak stačí do původního cyklu, který způsoboval problém, vložit nějakou drobnou prodlevu:
while (some_variable == SOME_CONST) { try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } }
Procesor bude sice stále zatěžován zbytečným čekáním, ale mnohem méně.