NOVINKA - Online rekvalifikační kurz Java programátor. Oblíbená a studenty ověřená rekvalifikace - nyní i online.
NOVINKA – Víkendový online kurz Software tester, který tě posune dál. Zjisti, jak na to!

Diskuze: GPIO pin listener - vlákna

V předchozím kvízu, Online test znalostí Java, jsme si ověřili nabyté zkušenosti z kurzu.

Aktivity
Avatar
nalimleinad
Člen
Avatar
nalimleinad:19.1.2017 9:53

Používám klasický listener na detekci 3V3 napětí v pinu.

pinButton.addListener(new GpioPinListenerDigital() {
            @Override
            public void handleGpioPinDigitalStateChangeEvent(GpioPinDigitalStateChangeEvent event) {
        });

Detekce funguje v pořádku, avšak potřebuji to, aby když mi sepne listener, tak nemohl X sekund poté sepnout znovu. Zkoušel jsem klasický

Thread.sleep(int miliseconds);

bohužel listener si vždy vytvoří nové vlákno, když to předchozí je uspané.

Jak tedy docílit, aby se listener probudil opět až X sekund po jeho aktivaci ?

 
Odpovědět
19.1.2017 9:53
Avatar
Petr
Člen
Avatar
Odpovídá na nalimleinad
Petr:19.1.2017 11:36

Tohle do tridy, kde mas definovany ten pinButton

private static final AtomicLong lastActivation = new AtomicLong(System.currentTimeMillis()); //atomic long neni nutny, jen sem liny psat novou tridu s jednim atributem typu volatile long a getterem / setterem, na jejiz instanci bych to mohl zamknout
private static final long nextActivationStep = 1000 * 5; // 5 sekund

Tohle dovnitr metody, ktera se vola pri aktivaci listeneru. A jestli to mas do skoly tak si precti a pripadne uprav komentare :)

long previousActivation = lastActivation.get();
long currentTime = System.currentTimeMillis();
if (previousActivation + nextActivationStep < currentTime) {
    synchronized (lastActivation) { //k uzamknuti dojde az ve chvili kdy je predchozi podminka splnena
        previousActivation = lastActivation.get();
        currentTime = System.currentTimeMillis();
        // uvnitr synchronized bloku je nutne overit podminku znovu, protoze se teoreticky mohla potkat dve vlakna a druhe vlakno
        // by vstoupilo do synchronized bloku pote co cekalo nez jine vlakno synchronized blok opusti
        if (previousActivation + nextActivationStep < currentTime) {
            lastActivation.set(currentTime);
            // funkcni kod listeneru prijde sem
        }
    }
}
Akceptované řešení
+20 Zkušeností
+2,50 Kč
Řešení problému
 
Nahoru Odpovědět
19.1.2017 11:36
Avatar
nalimleinad
Člen
Avatar
Odpovídá na Petr
nalimleinad:20.1.2017 15:11

Díky, něco na tenhle způsob mě napadlo, jen jsem si říkal, že by to asi mohlo jít i jinak, nějakou standardní cestou. Tak jsem se asi pletl. :-)

 
Nahoru Odpovědět
20.1.2017 15:11
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 3 zpráv z 3.