Problema programmazione concorrente

di il
12 risposte

Problema programmazione concorrente

Buonasera a tutti,
ho scritto un programma in programmazione concorrente, usando semafori binari e contatori per proteggere le variabili condivise e ho fatto varie prove modificando il numero di thread di alcune classi.
Fino a 50 thread il programma va perfettamente, infatti credevo che il programma non avesse errori.
Ma dagli 80 thread in poi il programma termina ma genera un sacco di eccezioni, del tipo
at java.base/java.util.concurrent.locks.ReentrantLock$Sync.tryRelease(ReentrantLock.java:149)
at java.base/java.util.concurrent.locks.AbstractQueuedSynchronizer.release(AbstractQueuedSynchronizer.java:1302)
at java.base/java.util.concurrent.locks.ReentrantLock.unlock(ReentrantLock.java:439)
oppure
Exception in thread "Sensore_55" java.lang.IllegalMonitorStateException
Quest'ultima eccezione compare nonostante io non abbia usato monitor.
La mia domanda è : può il problema non essere dovuto al mio codice ma al numero elevato di thread che in qualche modo confliggono?

12 Risposte

  • Re: Problema programmazione concorrente

    Frank2000 ha scritto:


    Exception in thread "Sensore_55" java.lang.IllegalMonitorStateException
    Quest'ultima eccezione compare nonostante io non abbia usato monitor.
    IllegalMonitorStateException generalmente riguarda il tentativo di usare i wait()/notify() su un oggetto senza aver prima acquisito il lock ("monitor") su quell'oggetto. Ovvero non avendo usato correttamente la parola chiave synchronized.

    Frank2000 ha scritto:


    La mia domanda è : può il problema non essere dovuto al mio codice ma al numero elevato di thread che in qualche modo confliggono?
    Dubito molto ma bisognerebbe vedere il codice. Se è qualcosa di postabile (non lunghissimo, non riservato/privato, ecc...) postalo pure, che vediamo.
  • Re: Problema programmazione concorrente

    andbin ha scritto:


    Frank2000 ha scritto:


    Exception in thread "Sensore_55" java.lang.IllegalMonitorStateException
    Quest'ultima eccezione compare nonostante io non abbia usato monitor.
    IllegalMonitorStateException generalmente riguarda il tentativo di usare i wait()/notify() su un oggetto senza aver prima acquisito il lock ("monitor") su quell'oggetto. Ovvero non avendo usato correttamente la parola chiave synchronized.

    Frank2000 ha scritto:


    La mia domanda è : può il problema non essere dovuto al mio codice ma al numero elevato di thread che in qualche modo confliggono?
    Dubito molto ma bisognerebbe vedere il codice. Se è qualcosa di postabile (non lunghissimo, non riservato/privato, ecc...) postalo pure, che vediamo.
    Il codice è un pò lunghino... purtroppo devo trovare l'errore entro domani. comunque non ho usato nè wait ne notigy
  • Re: Problema programmazione concorrente

    Frank2000 ha scritto:


    Il codice è un pò lunghino... purtroppo devo trovare l'errore entro domani.
    Puoi postare magari solo le parti che interessano la sincronizzazione? Se hai fatto il design in modo sensato, dovresti aver incapsulato il più possibile l'uso della sincronizzazione. Se non l'hai fatto, hai sparpagliato l'uso di semafori o quant'altro su molto codice, con le problematiche che ne conseguono ... (poco comprensibile, fragile, non facilmente riutilizzabile, ecc...)

    P.S. "entro domani" che orario intendi?
  • Re: Problema programmazione concorrente

    andbin ha scritto:


    Frank2000 ha scritto:


    Il codice è un pò lunghino... purtroppo devo trovare l'errore entro domani.
    Puoi postare magari solo le parti che interessano la sincronizzazione? Se hai fatto il design in modo sensato, dovresti aver incapsulato il più possibile l'uso della sincronizzazione. Se non l'hai fatto, hai sparpagliato l'uso di semafori o quant'altro su molto codice, con le problematiche che ne conseguono ... (poco comprensibile, fragile, non facilmente riutilizzabile, ecc...)

    P.S. "entro domani" che orario intendi?
    ciao, ho pubblicato un altro argomento con parte delle eccezioni generate e il codice che dovrebbe contenere l'errore. L'orario è entro stanotte... se riesci a dare un'occhiata mi faresti un grosso piacere
  • Re: Problema programmazione concorrente

    Non ho capito bene la tua architettura. In teoria i sensori non possono aspettare, perché solitamente funzionano con tempistiche precise. Quindi ognuno dovrebbe avere il suo bel buffer circolare sul quale poter scrivere liberamente (quando vuole lui) e attivare un semaforo che blocca la lettura degli utenti

    Prova a togliere anche tutte le System.out.println() (quantomeno per i sensori)
  • Re: Problema programmazione concorrente

    Weierstrass ha scritto:


    Non ho capito bene la tua architettura. In teoria i sensori non possono aspettare, perché solitamente funzionano con tempistiche precise. Quindi ognuno dovrebbe avere il suo bel buffer circolare sul quale poter scrivere liberamente (quando vuole lui) e attivare un semaforo che blocca la lettura degli utenti

    Prova a togliere anche tutte le System.out.println() (quantomeno per i sensori)
    No i buffer circolari sono condivisi, è proprio queste la specifica del progetto
  • Re: Problema programmazione concorrente

    Ok

    Hai controllato che non vada in eccezione la riga di acquire() sul semaforo prima del lock()? Se va in eccezione prima di aver acquisito il lock, poi all'esecuzione del finally avrai IllegalMonitorStateException.

    Magari prova a mettere i catch anche in writeData()
  • Re: Problema programmazione concorrente

    Weierstrass ha scritto:


    Ok

    Hai controllato che non vada in eccezione la riga di acquire() sul semaforo prima del lock()? Se va in eccezione prima di aver acquisito il lock, poi all'esecuzione del finally avrai IllegalMonitorStateException.

    Magari prova a mettere i catch anche in writeData()
    Ciao, scusa il ritardo. Ho risolto nella classe cloud tirando fuori le seguenti righe dal try
    this.notEmptyLum.acquire(4);
    this.lckLum.lock();
    Ma perchè si risolve in questo modo?
  • Re: Problema programmazione concorrente

    Non ho idea di che diamine succeda con Java a basso livello, però sicuramente l'errore era dovuto all'unlock() dentro il finally{} e quindi l'inghippo doveva essere per forza nelle prime righe quando ancora il lock non è acquisito.

    La documentazione ufficiale ti dice che è raccomandato mettere sempre il lock() immediatamente prima del try{}

    https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/locks/ReentrantLock.html

    Il motivo tecnico non avevano voglia di spiegarlo.
  • Re: Problema programmazione concorrente

    Weierstrass ha scritto:


    Non ho idea di che diamine succeda con Java a basso livello, però sicuramente l'errore era dovuto all'unlock() dentro il finally{} e quindi l'inghippo doveva essere per forza nelle prime righe quando ancora il lock non è acquisito.

    La documentazione ufficiale ti dice che è raccomandato mettere sempre il lock() immediatamente prima del try{}

    https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/locks/ReentrantLock.html

    Il motivo tecnico non avevano voglia di spiegarlo.
    Ok grazie, speriamo che l'errore era per quel motivo e non per altri...
  • Re: Problema programmazione concorrente

    Il motivo ""tecnico"" del perche' il lock vada messo PRIMA del try e' abbastanza ""ragionevole""

    SE "lock.lock()" fallisce, non c'e' nessun lock da rilasciare.
    Se lo metti DENTRO il try, viene necessariamente eseguito il finally che TENTA di eseguire "lock.unlock()" su un lock non acquisito con generazione di UN'ALTRA eccezione che nasconderebbe la prima.

    Sono quelle regolette ""spicciole"" che se vengono sempre seguite risolvono l'80% delle rogne rognose.

    Altre semplici regolette:

    1) se si devono acquisire PIU' lock in sequenza, gli unlock devono essere fatti SEMPRE in ordine INVERSO
    2) acquisire i lock SEMPRE usando l'ordine lessicografico delle variabili che contengono le variabili di soncronizzazione.
  • Re: Problema programmazione concorrente

    @migliorabile.

    Grazie della spiegazione, in effetti ha senso.
    In ogni caso non si capisce perché un thread che rimane dormiente (secondo la documentazione) debba comunque eseguire il blocco finally. Due parole in proposito potevano spenderle
Devi accedere o registrarti per scrivere nel forum
12 risposte