Você está na página 1de 1

Esercizio 2 – Programma Java

La consegna dell’esercizio da svolgere in Java è analogo al precedente da svolgere in C con la


variante dell’utilizzo di semafori per la sincronizzazione e mutua esclusione tra thread.
Abbiamo creato come prima cosa due classi che rappresentano i due thread in esecuzione
concorrente dove uno effettuerà il conteggio delle sequenze composte da 0x00 (WorkerZero) e
l’altro delle sequenze composte da 0xFF (WorkerEffe); a queste assegneremo un nome proprio
identificativo per la stampe in output ed ad ognuna passeremo come parametro nel metodo
costruttore elementi essenziali per il processa mento delle varie sequenze e per la comunicazione
con il main che li ha fatti partire.
Nel main appunto verranno eseguite le prime operazioni di default riguardanti il controllo del giusto
numero di parametri un input, l’apertura dell’input file (condizione necessarie che sia presente nel
file system e che possa essere leggibile…) ; successivamente metteremo in un buffer di byte
(buffer) l’insieme dei caratteri letti da file, subito dopo questi verranno trasformati in tipo short
tramite l’operazione  xxx = (short)(Buffer[i] & 0x00FF); poiché nel linguaggio Java non è
previsto il tipo “unsigned byte” usato nel C.
I caratteri trasformati senza segno verranno messi in un buffer definitivo buffer2 a cui
aggiungeremo un carattere “sentinella” -1 che indica ai thread che leggono da questo la fine dei
caratteri da leggere.
Componenti che stanno alla base della comunicazione sono due semafori:
• eventSem: semaforo evento che invia segnali temporali da thread a processo creatore di
questi per segnalare la fine del processa mento dei caratteri
• maxSem: semaforo Mutex che garantisce la mutua esclusione nell’utilizzo dell’oggetto di
tipo Max.

Il compito eseguito dai thread (analogo per entrambi) è quello contenuto nel corpo del proprio
metodo run nel quale esso non fa altro che ciclare fino a che dal buffer contenente i caratteri del file
non si legga il carattere sentinella -1; nel caso in cui si legga un carattere valido si incrementa il
contatore e l’indice riferito al buffer di caratteri, se il prossimo carattere che arriverà in ingresso non
appartiene alla sequenza propria del thread, questo stampa il valore del contatore di sequenza e lo
inserisce nell’oggetto che tiene conto di tutte le dimensioni, ovvero seqMax.
Se il successivo carattere è invece il terminatore se inserisce la nuova sequenza e si rompe il ciclo,
eseguendo poi la release(); che indica al main la fine della propria esecuzione
Il main, ricevuti e segnali temporale da tutti e due i thread, da seqMax, ottiene quella che è la
sequenza di dimensioni maggiori.
Merita una piccola analisi l’oggetto di tipo Max: esso è l’oggetto che tiene conto di informazioni
vitali riguardanti tutto il processo risolutivo, permette di introdurre il concetto di indice che
rappresenta il puntatore all’elemento puntato nel buffer di caratteri senza segno; ad esso sono
dedicati due metodi getIndice e setIndice che sono dichiarati di tipo synchronized poiché la
scrittura simultanea su di essi può causare conflitti (ciò è stato verificato da alcune prove).
Tale oggetto mantiene inoltre l’array vectCount che funge da vettore di contatori (interi) di tutte le
sequenze, dove i thread ne aggiungono di nuovi con il metodo insertCount ed il main ricava la
dimensione della sequenza più grande tramite il metodo getMax dove si scorrono tutti gli elementi
per poi confrontarli con max, inizializzato a zero.

Você também pode gostar