DOMANDA Dubbio sull'utilizzo dei semafori in Java

Simone Trombiero

Nuovo Utente
16
0
Salve, sto provando a fare esercizi sulla programmazione concorrente in Java ma ho un dubbio sull'utilizzo dei semafori per leggere da una risorsa condivisa.

La traccia dell'esercizio è questa:

Delle persone frequentano una piscina per esercitarsi nel nuoto. La piscina è composta da 5 corsie, ciascuna delle quali può essere usata al più da 4 persone contemporaneamente. Ogni persona sceglie la corsia occupata dal mi-nor numero di persone: se la piscina è al completo, sceglie una corsia in maniera casuale e attende in ordine FIFO. Non appena entra in corsia, nuota per un tempo tra 30 e 60 minuti, quindi si fa la doccia (20 minuti), dopodiché va via. La piscina è gestita da un istruttore che deve controllare tutte le attività che si svolgono nelle corsie. L’istruttore ogni giorno gestisce due turni: la mattina tiene aperta la piscina per 4 ore, poi fa una pausa di 1 ora, e riapre la piscina per il turno pomeridiano di 5 ore. Nessuna persona può entrare in piscina se non è presente l’istruttore. Alla chiusura della piscina (sia alla pausa sia alla chiusura finale), se sono presenti delle persone nelle corsie, l’istruttore forza le persone ad uscire dalla piscina. Le persone devono immediatamente liberare la piscina, terminando in anticipo l’attività in acqua e andando subito a fare la doccia.

Per implementare le corsie uso i due seguenti array:
Codice:
int[] corsie=new int[5];
Semaphore[] corsieSem=new Semaphore[5];
ed inizializzo ogni semaforo a 4.

Il mio dubbio è il seguente: nel metodo che si occupa di scegliere la corsia meno affollata, quindi che cerca l'indice del minimo nell'array di interi, devo utilizzare un semaforo di mutua esclusione? Io credo di si, ed ho trovato queste soluzione, ma non ne sono sicuro:
Codice:
private Semaphore mutexCorsie=new Semaphore(1);

int corsiaMenoOccupata() throws InterruptedException {        
       mutexCorsie.acquire();
       int indiceMin=indiceMin(corsie);
       if(corsie[indiceMin]==4){
           mutexCorsie.release();
           return random.nextInt(5);
       }
       mutexCorsie.release();
       return indiceMin;
}

Grazie per l'eventuale risposta.
 

lpleo

Nuovo Utente
33
10
Ciao!

Se ho capito bene la domanda la risposta è sì, perché la grandezza degli array è una risorsa condivisa mutevole e come tale va trattata. L'unico mio dubbio è se non ti converrebbe trattare come atomica anche tutta la parte dell'aumento del contatore delle corsie.

(Sperando i miei ricordi siano ancora buoni...) Tecnicamente se non fai così potresti avere due processi che eseguono il metodo che hai stampato sopra, e supponiamo che venga ritornato corsia 1 ad entrambi, perché magari la dimensione della corsia era 3. Quindi convinti che sia tutto ok aumentano entrambi il contatore nella corsia arrivando a 5.

Spero di essere stato d'aiuto e di non averti incasinato le idee... comunque prendi queste cose con le pinze che per me è roba che inizia a diventare vecchiotta :D
 

Simone Trombiero

Nuovo Utente
16
0
Innanzitutto grazie per la risposta!
Anche il metodo di incremento del contatore delle corsie l'ho implementato utilizzando il semaforo di mutua esclusione, ma in più utilizzo un semaforo contatore per ogni corsia istanziato a 4 in modo che anche se viene fatta la stessa scelta da più processi non si supera mai il numero massimo:
Codice:
private Semaphore[] corsieSem=new Semaphore[5];
        for(int i=0;i<5;i++){
            corsieSem[i]=new Semaphore(4,true);
}

void entraENuota(int numeroCorsia) throws InterruptedException {
        corsieSem[numeroCorsia].acquire();
        mutexCorsie.acquire();
        corsie[numeroCorsia]++;
        System.out.println(super.toString());

        mutexCorsie.release();
}

Il mio dubbio sta proprio nel capire se è un problema o meno che due thread che eseguono quasi contemporaneamente il metodo di ricerca della corsia possono scegliere la stessa corsia, proprio concettualmente, poichè effettivamente non causa alcun problema. Mi chiedo solo se questo evento potrebbe farmi uscire dalla traccia e se c'è un modo affinchè due thread scelgano sempre diversamente.
 

Entra

oppure Accedi utilizzando
Discord Ufficiale Entra ora!