Newsgroup: it.comp.java
Titolo: Problema multithreading

Salve a tutti.
Vengo subito al dunque: io ho in un mio programma Java un certo numero di
threads che devono accedere ad una determinata risorsa (un oggetto Vector
per l'esattezza), e voglio che tutti i threads che devono leggere il
Vector possano accedervi anche contemporaneamente; al contrario, quelli
che devono modificare il Vector dovranno accedervi solo uno per volta,
escludendo anche quelli che vi accedono solo per lettura.
Infatti se un thread accede al Vector per modificare il numero di elementi
contenuti, altri thread non possono accedervi ne' per lettura ne' per
scrittura, altrimenti l'oggetto potrebbe trovarsi in uno stato
inconsistente al momento dell'accesso.
In altre parole quindi l'esclusione per l'accesso alla risorsa deve essere
"mutual" per i threads che la modificano, ma non č necessario che lo sia
per quelli che la leggono. Anzi, per rendere piů veloce il mio programma
(che, per la cronaca, č un server TCP/IP in cui ogni thread gestisce una
connessione ad un client) vorrei proprio che piů threads potessero leggere
la risorsa contemporaneamente.
Ora, forse sono io che sono ignorante dal momento che č uno dei miei primi
programmi java, ma mi sembra che gli strumenti messi a disposizione dal
linguaggio per la sincronizzazione dei threads (come la parola chiave
synchronized e le funzioni lock, unlock, wait, ecc. di Object) permettano
solo di gestire esclusioni "mutue"; in che modo dunque secondo voi posso
risolvere il problema?
Nota: il mio problema in questo momento riguarda specificamente il Java,
ma talvolta mi sono posto le stesse domande anche programmando in altri
ambienti, soprattutto in Win32 col C/C++.
Ringrazio vivamente ogni suggerimento.
-- 
questo articolo e` stato inviato via web dal servizio gratuito 
http://www.newsland.it/news
 segnala gli abusi ad 
ab...@newsland.it

Ciao,
quello che chiedi è un classico problema legato alla concorrenza.
Prova a cercare su google "Il problema dei Lettori e degli Scrittori"
Troverai svariate implementazioni in java.
In bocca al lupo.
Ciao,
Kimbuba.

Un paio di anni fa ho realizzato un progetto universitario con i thread, se 
non ricordo male per ottenere la mutua sclusione bisogna utilizzare 
synchronized. Cerca un pò sulla guida.
Ciao
ReDiCuori
-- 
L'informatica è un' arte
---------------------------------------------------------
 
www.pascallike.too.it
 
http://utenti.lycos.it/pascallike
 il sito sulla programmazione pascal
 sorgenti, tutorial ed utility
------------------------------------------------------------
www.treves-srl.com
Libreria Internazionale Treves
Via Toledo 249/250 Napoli
------------------------------------------------------------
www.alphalibri.com
Vendita ingrosso di libri
Via S.Anna dei Lombardi 10 , Napoli
--------------------------------------------------------- 

 ha scritto nel messaggio 
news:aLL9d.4626$1p....@nntpserver.swip.net...


No. Attenzione la risorsa condivisa va lockata sia in scrittura che in 
lettura sta poi ad un monitor sincornizzare i threads. Leggiti il 
problema dei lettori e scrittori che è un classico problema da Sistemi 
Operativi - Concorrenza.
Ciao,
Kimbuba


 normali quelli che la leggono solamente?
Il fatto è che nessuno deve poter leggere mentre qualcuno scrive.
-- 
chi sono e soprattutto chi non sono:
http://www.ilnomedeldominio.it
un piccolo programma per studenti universitari:
http://inutility.ilnomedeldominio.it/imsv/

 ha scritto nel messaggio
news:4167...@x-privat.org...

 ha interrotto con la ridicola scusa:
avrò anche sbagliato, ma ho sbagliato cercando di aiutare, ma il tuo 
commento è un inutile presa in giro che denota maleducazione!


Stavo sfogliando le pagine di una "rivista specializzata" quando esrever mi
ha interrotto con la ridicola scusa:
E' vero che è un tipico problema, ma non mi risulta che la cosa si possa
implemntare con i soli strumenti forniti dal linguaggio.
L'idea è questa:
due variabili tengono il conto di quanti lettori e scrittori stanno
accedendo alla risorsa. Per i primi ci vuole un int, per i secondi basta un
boolean (un solo scrittore per volta).
Diamo dei nomi alle variabili, tanto per capirci:
int readers;
boolean writer;
A questo punto, ecco l'algoritmo.
Lettore
--Accesso
if(!writer) {
  reader++;
  <faccio quello che mi pare>
}
else
 <aspetto>
-- Rilascio
 reader--;
Scrittore
--Accesso
if(!writer && readers==0){
   writer = true;
   <faccio quello che mi pare>
}
else
  <aspetto>
-- Rilascio
  writer = false.
Al lettore attento (ho sempre sognato scriverlo :) non sarà sfoggito che
questo pone un problema di starvation. I lettori possono impedire
indefinitamente agli scrittori di accedere alla risorsa (la variabile
readers potrebbe non diventare mai 0).
La cosa va in qualche modo risolta. Non mi ricordo i cosa dicono i sacri
testi in merito. A me verrebbe in mente che gli scrittore possono
"prenotare" il loro accesso. Cioè quando uno scrittore tenta di accedere e
non puo' prenota il suo accesso, e da quel momento non si accettano più
lettori. Quando quelli presenti hanno finito lo scrittore puo' procedere.
Provo a passare dalla teoria alla pratica. Premetto che scriverò
direttamente nel newsreader quindi probabilmente quello che scrivo conterrà
svariati errori :)
public class Controllore {
private int readers;
private boolean writer;
private boolean prenotato;
public synchronized void richiestaLettore() {
  boolean fatto = false;
 do {
   if(!writer && !prenotato) {
     readers++;
     fatto = true;
   }
   else 
     wait(); //si mette in coda e aspetta;
  }while(!fatto);
}
public void rilascioLettore() {
  synchronized(this) {
    readers --;
  }
  if(readers == 0)
    notifyAll(); //sveglia!! qualche scrittore potrebbe essere
                //dormiente
}
public synchronized void richiestaScrittore() {
 
  boolean fatto = false;  
  do {
    if(!writer && readers == 0) {
      writer = true;
      prenotato = false;
      fatto = true;
    }
    else {
      prenotato = true;
      wait();
    }
  } while(!fatto);
}
public void rilascioScrittore() {
  synchronized(this) {
    writer = false;
  }
  notifyAll();
}
}
Spero di non averne sparate troppo, vado un po' di fretta :)
Ciao
Matteo


 commento è un inutile presa in giro che denota maleducazione!
Quella cosa c'é in tutti i miei messaggi. Non è una presa in giro è solo una
cosa "simpatica" (cioé simpatica secondo me) da mettere al posto del
solito: "tizio ha scritto".
Non era un'offesa ne una bacchettata


 Non era un'offesa ne una bacchettata
...che figuraccia...ne ho fatte due adesso! Allora le scuse te le faccio io, 
non sapevo fosse così...ed in effetti è una simpatica idea.
:)
Innuendo


 In bocca al lupo.
crepi :)


 Spero di non averne sparate troppo, vado un po' di fretta :)
Al contrario, mi sei stato di grande aiuto :) già immaginavo che la cosa
non si potesse risolvere in maniera standard e pensavo di scrivermi a
manina una sorta di oggetto sincronizzatore che facesse al caso mio;
invece mi trovo il lavoro già fatto, giusto da riadattare un po' al mio
programma :)
Grazie ancora e ciao.
P.S.: cmq quel tuo heading che metti ad ogni post è decisamente equivoco
per i niubbi: sembra effettivamente un insulto... e poi cosa intendi per
"rivista specializzata"? lol... :D


 Spiegami meglio magari.
La tua potrebbe essere un'idea, ma come dice matish non vale nel caso in
cui i lettori vadano a leggere proprio mentre è in atto una scrittura. :)


 producer/consumer 
Il tuo in effetti è un tipo di produttore/consumatore ma con una differenza.
Nel problema vero e proprio il dato viene appunto consumato, cioé tolto
dalla struttura. Questo risolve molti problemi di sincronizzazione perché
un volta garantita la mutua esclusione nel codice che "stacca" e "attacca"
pezzi alla struttura non ci sono altri problemi. Nel tuo caso invece i
lettori lasciano lì il dato, che quindi deve essere contemporaneamente
disponibile ad altri lettori. In oltre il problema del
produttore/consumatore non soffre della starvation perché quando la
struttura è vuota devono per forza accedere dei produttori. 
In poche parole non puoi usare le soluzioni per quel problema così come le
trovi.
Altrimenti sarebbe bastato un Vector.
Ciao
Matteo


 "rivista specializzata"? lol... :D
Quello che secondo il mio, evidentemente poco condiviso, senso dell'umorismo
dovrebbe far ridere è proprio il doppio senso. Potrebbe benissimo essere PC
Professionale come... qualcos'altro ;) In effetti la presunta comicità sta
nelle virgolette :P


 escludendo anche quelli che vi accedono solo per lettura.
E' un problema abbastanza diffuso, per esempio è fondamentale per
implementare alcuni tipi di cache. Basta scaricare le concurrency
utilities di Doug Lea e ti troverai un bel Reader/Writer lock che fa
proprio quello che vuoi tu.
Implementarselo da solo è ovviamente possibile ma non semplicissimo da
realizzare correttamente, te lo sconsiglio.
Se poi se fortunato è stai lavorando sul JDK 1.5, il package di Doug Lea è
diventato parte del core di Java, quindi oltre al reader/writer lock hai
addirittura delle collection già fatte che si comportano proprio come
serve a te (in questo caso devi eliminare il Vector, ovviamente)
hth
uL
