Ciao. Devo realizzare un progetto che mi permetta di fare un po' di pratica sugli algoritmi di accesso e terminazione distribuita. Quello che è richiesto è semplicemente un sistema dove ci sono n nodi che hanno una memoria con lo stesso contenuto, e ogni volta che un nodo la modifica avverte gli altri perché facciano la stessa modifica, in modo che in stato di quiete i nodi hanno la memoria con lo stesso contenuto. Il tutto regolato dagli algoritmi di accesso e terminazione distribuita.
Ogni nodo offre dei metodi per lavorare sulla memoria, per esempio per inserire o cancellare degli elementi.
Da come la vedo io, mi pare una situazione simile al paradigma produttore-consumatore, soltanto che è anche distribuita, quindi tanto per portare avanti l'esempio del produttore-consumatore, io mi trovo ad avere queste differenze:
1) è come se avessi un produttore "o" un consumatore per ogni nodo, e un buffer ( la mia struttura dati con cui rappresento la memoria richiesta dalle specifiche ) per ogni nodo, tutti i buffer con lo stesso contenuto in stato di quiete del sistema.
2) nella realtà però, non ho una rete con n nodi, bensì un solo computer dove faccio girare n thread che mi simulano il meccanismo della rete.
Il mio problema è questo:
Esistono questi algoritmi a cui accennavo e servono per ottenere accesso in un sistema distribuito, e una volta ottenuto il permesso ci sono algoritmi che permettono di lavorare ( in tranquillità grazie al primo algoritmo ) sui dati e comunicare poi che è finita l'operazione e quindi rilasciare l'accesso ad altre richieste dopo aver comunicato agli altri nodi eventuali
modifiche.
Sono gli algoritmi argomento del corso, che sto cercando di implementare per realizzare il progetto, però non so se a questo punto devo usare i costrutti della concorrenza, come synchronized, Semaphore ecc... in quanto ho comunque n thread sullo stesso computer, poi non capisco dove eventualmente usare questi costrutti, cioè non so se esistono delle classi del mio progetto ( non solo quelle degli algoritmi distribuiti ) dove devo mettere dei metodi synchronized per esempio.
A grandi linee ho strutturato il progetto in questo modo:
1) Un main che lancia n thread
2) i thread lanciati sono oggetti che si occupano di creare gli elementi necessari per far andare la rete, quindi ci sarà Nodo, un gestore che si occupa della comunicazione con gli altri Nodi tramite channels, gli algoritmi detti sopra per l'accesso e terminazione distribuita, i Packet ecc.... e si occupa di far partire il Nodo.
3) La classe dei Nodi, che lavorano sull'oggetto memoria con i metodi richiesti dalle specifiche, regolati dal permesso di accedere alla memoria dall'algoritmo distribuito e poi lavorano sulla memoria con l'algoritmo che poi comunica la fine dell'operazione
4) l'oggetto memoria
5) le classi per i 2 algoritmi distribuiti, che hanno dei thread inner class che ascoltano l'arrivo di richieste varie
Tanto per rendere l'idea di che cosa fanno gli algoritmi, che forse può essere utile per capire la situazione:
se per esempio un nodo vuol fare un inserimento:
codice:
public void insert( int valore )
{
mutuaEsclusioneDistrib.enter(); // serve per chiedere agli altri nodi di
//poter accedere alla memoria per poi
//lavorarci, lo offre la mia implementazione
//di uno dei 2 algoritmi
terminazioneDistribuita.eseguo(......); // fa qualcosa sulla memoria e poi si
//può lasciare il semaforo
//anche questa è una funzionalità di uno dei 2 algoritmi
mutuaEsclusioneDistrib.leave();
}
Questo in sintesi il cuore del progetto, accompagnato da classi di contorno per cose secondarie.
Ho a disposizione delle classi, diciamo che sono un po un punto di partenza, farnite per esempio per avere già il gestore della comunicazione, con le socket, i channel ecc... e lì ho notato che tutti i metodi sono synchronized, da qui è sorto il dubbio di chi e dove nel suo codice deve essere synchronized.
Se qualcuno mi sa dare un consiglio mi fa molto piacere, è un aspetto del progetto che penso sia fondamentale, sia di concetto che di correttezza del funzionamento.
Grazie