Joomla Vorlagen by Website Hosting

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ě.