Avatar
Acerik
Redaktor
Avatar
Acerik:

Dobrý den, učím se vlákna tak sem si udělal bankomat. Má každou vteřinu přidat peníze na účet. Možnost zastavit vlákno a dát ho pokračovat. Ale když chci po vláknu kde je smyčka aby přidalo peníze a aktualizovalo staty. Dostanu error. Jinak vlákno bez těchto metod viz níže funguje

Zdroják vlákna

package bankomat;

import java.util.logging.Level;
import java.util.logging.Logger;

public class Vlakno extends Thread {

    Ucet ucet;
    Okno okno;
    Bankomat bankomat;
    int i = 0;
    boolean pockat = false;

    public void run() {
        while(true){
            i++;
            System.out.println(i);

            ucet.cas();
            okno.update(this);

            try {
                sleep(1000);
            } catch (InterruptedException ex) {
                Logger.getLogger(Vlakno.class.getName()).log(Level.SEVERE, null, ex);
            }
            synchronized (this) {
                while(pockat){
                    try {
                        wait();
                    } catch (InterruptedException ex) {
                        Logger.getLogger(Vlakno.class.getName()).log(Level.SEVERE, null, ex);
                    }
                }
            }
        }
    }
}

Zdroják metody cas

public void cas(){
        penize += prijem;
    }

Zdroják metody update

public void update(Vlakno vlakno) {
        money.setText("Peníze: " + ucet.penize);
        ucetMoney.setText("Stav účtu: " + ucet.penizeUcet);
        prijem.setText("Čas: " + vlakno.i);
    }

Error

Exception in thread "Thread-0" java.lang.NullPointerException
        at bankomat.Vlakno.run(Vlakno.java:19)
Editováno 7. července 22:04
Odpovědět 7. července 22:03
Praxe na IT škole? Obrábění kovů for the win
Avatar
pocitac770
Redaktor
Avatar
pocitac770:

NullPointerEx­ception, tzn. jsi někde nezinicializoal proměnnou. Jaký řádek je u tebe v IDE označen číslem 19 (je to v metodě run)? Tam najdeš chybné volání metody na objektu, který vlastně "neexistuje".

Editováno 7. července 23:07
 
Nahoru Odpovědět 7. července 23:06
Avatar
pocitac770
Redaktor
Avatar
pocitac770:

Jenom... zde bych ti doporučil si přečíst něco o zapouzdření. Jak jsem říkal, někde nemáš zinicializovanou proměnnou. Je to způsobno tím, že objekty pravděpodobně dosazuješ z vnějšku třídy přímo, a zároveň můžeš zavolat metodu run() dříve, než bude všechno připraveno. Proto by bylo lepší si ony důležité objekty (atributy) nastavit jako privátní (ucet, okno, bankomat), vytvořit ke třídě konstruktor a doplnit je tam (předání přes parametry konstruktoru). Tím si zajistíš, že pokaždé, když si vytvoříš nové vlákno tohoto typu, tak bude vše připraveno k použití a následnému zavolání metody run()

Editováno 7. července 23:13
 
Nahoru Odpovědět 7. července 23:12
Avatar
Acerik
Redaktor
Avatar
Odpovídá na pocitac770
Acerik:

Error je na řádek s ucet.cas(); takže do run a vlákno zapínám až jako poslední. A zkontroloval sem si pomocí vypsaní do konzole že ty proměné jsou inicializované

Nahoru Odpovědět 7. července 23:59
Praxe na IT škole? Obrábění kovů for the win
Avatar
Hartrik
Redaktor
Avatar
Odpovídá na Acerik
Hartrik:

Jiné vysvětlení, než že tam máš null, není.

BTW: měnit vlastnosti objektům ve scéně z jiného než aplikačního vlákna je zakázáno.
To platí ve Swingu i v JavaFX

Editováno 8. července 0:59
 
Nahoru Odpovědět 8. července 0:59
Avatar
Acerik
Redaktor
Avatar
Odpovídá na Hartrik
Acerik:

Takže ten update? Jestli to chápu dobře...

Nahoru Odpovědět 8. července 1:09
Praxe na IT škole? Obrábění kovů for the win
Avatar
Hartrik
Redaktor
Avatar
Odpovídá na Acerik
Hartrik:

Jo, tam bude další chyba.

 
Nahoru Odpovědět 8. července 1:12
Avatar
Acerik
Redaktor
Avatar
Odpovídá na Hartrik
Acerik:

Ano, už sem vyrešil tu inicializaci že sem musel udělat rovnou

int penize = 5000;
//takhle všechny

ale tady mám další error.. Nějaká rada jak tedy aktualizovat ty staty?

Nahoru Odpovědět 8. července 1:18
Praxe na IT škole? Obrábění kovů for the win
Avatar
Atrament
Člen
Avatar
Odpovídá na Acerik
Atrament:

Tohle je špatně, nejen z hlediska vláken, ale i z hlediska objektově orientovaného návrhu aplikace. Pominu teďka to OOP a zaměřím se na vlákna.

Vlastní vlákno pomocí rozšíření Thread se pro periodicky se opakující akce obvykle nedělá, od toho je tu Timer - https://docs.oracle.com/…g/Timer.html

Vlákna pomocí rozšíření Thread se obvykle dělají, když předem nevíš jak přesně dlouho nějaká akce bude trvat, a tak chceš, aby ta akce běžela na pozadí a neblokovala například ui.

 
Nahoru Odpovědět 8. července 9:01
Avatar
wgamez101
Člen
Avatar
Odpovídá na Acerik
wgamez101:

No musíš inicializovať aj objekty ucet, okno a bankomat v triede Vlakno, preto ti vyhodí tu chybu lebo sú null. A tie Swingové metódy by si mal volať na EDT, nejak takto.

public void update(final Vlakno vlakno) {
    SwingUtilities.invokeLater(() -> {
        money.setText("Peníze: " + ucet.penize);
        ucetMoney.setText("Stav účtu: " + ucet.penizeUcet);
        prijem.setText("Čas: " + vlakno.i);
    });
}

Mimochodom, ten kód píšem z mobilu takže tam môžu byť chyby.

Nahoru Odpovědět 8. července 9:01
Inspiration is for amateurs - I just get to work.
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 10 zpráv z 10.