PDA

View Full Version : [java]problema multithread e oggetto da istanziare una sola volta


SHIVA>>LuR<<
02-07-2011, 19:29
ciao a tutti
premetto che sono un novizio di java e che mi sto affacciando adesso alla programmazione a oggetti dopo anni di C.
Ho da risolvere questo esercizio che mi sta facendo impazzire.
Devo:

implementare un server(multithread) e un client
il client interroga il server per verificare la presenza di un certo file sul server
stampare sul monitor del client il contenuto di un file presente sul server
il server mantiene traccia su una lista delle richieste ricevute
stampare sul monitor del client il contenuto di un file presente sul server


sono riuscito a implementare 1 2 e 4 il mio problema è il punto 3.
non riesco a istanziare l'oggetto solo una volta,dato che ogni volta che un client si collega creo un nuovo oggetto e quindi la lista è sempre vuota.

Questo è il codice della classe che dovrebbe occuparsi delle operazioni sul file inclusa anche la creazione della lista di cui al punto 3 dove vorrei inserire le richieste del client
import java.util.*;
import java.io.*;

public class opSuFile
{
private LinkedList <String> reqFileList;

public opSuFile()
{
reqFileList=new LinkedList <String> ();
}
public void addFileToList(String FileName)
{

reqFileList.add(FileName);

}
public void isPresent(String Filename)
{
try
{
FileReader in=new FileReader(Filename);
}
catch(IOException e)
{
System.out.println("file non presente");
}
}
public String getStringToServer(String str)
{
return str;
}
public void ReadFile(String Filename)
{
try
{
String s=null;
FileReader in=new FileReader(Filename);
BufferedReader br=new BufferedReader(in);
while((br.readLine())!=null)
{
s=br.readLine();
getStringToServer(s);
}
}
catch(IOException e)
{
System.out.println("file non presente");
}
}
public void saveFile(String FileName)
{
try
{
String s=null;
int c;

FileInputStream fis=new FileInputStream(FileName);
FileOutputStream fos=new FileOutputStream(FileName+".backup");
while((c=fis.read())!=-1)
{
fos.write((char)c);
}
}
catch(IOException exc)
{
System.out.println("impossibile salvare il file");
}
}
public void scorriLista()
{
for(int i=0;i<reqFileList.size();i++)
{
System.out.println("lista " + reqFileList.get(i)+);
}
}
}



in questa classe viene lanciato il metodo run ogni qual volta un client si collega.Qui c'è il problema perchè ogni volta che si collega un client io istanzio un nuovo oggetto opSuFile e la lista riparte da 0.


import java.net.*;
import java.io.*;
import java.util.*;

public class ServerThread extends Thread
{
private Socket s;
private opSuFile osf;

public ServerThread(Socket s)
{
this.s=s;
}


public void run()
{
try
{
osf=new opSuFile(); // il problema sta qui ogni volta che si collega un client io istanzio un nuovo oggetto e quindi parto sempre dal primo elemento della lista

BufferedReader br=new BufferedReader(new InputStreamReader(s.getInputStream()));
BufferedWriter bw=new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
String s=br.readLine();
osf.addFileToList(s);



}
catch(IOException e)
{
System.out.println("errore");
}
}


}

Esiste un metodo per istanziare l'oggetto quando il primo thread viene lanciato ?


grazie a tutti in anticipo

kevinpirola
03-07-2011, 15:19
così a grandi linee secondo me hai sbagliato già dall'inizio su come hai strutturato il tutto...

Io ti direi di fare così:

classe server:
thread, crea un socketserver e si mette in ascolto (ovviamente con opportuni cicli) verso il client, ogni volta che si connette un client crea un nuovo socket che sarà associato ad una classe clientlistener.

il client listener gestirà gli stream in e out del socket quelli in ingresso li smisterà verso una coda nella classe server. La classe server avrà al suo interno un qualche thread che eseguirà i messaggi leggendoli (e togliendoli) di volta in volta dalla coda.

In questo modo nel server puoi mettere qualsiasi linkedlist, hashtable, treemap o che dir si voglia e tramite metodi dell'esecutore dei messaggi aggiornarli ogni volta.

L'unica classe che istanzi ogni volta è il clientlistener (uno per client a cui è associato un socket), perciò la classe server e la classe esecutrice dei messaggi non sono istanziate più volte e mantengono i dati.


Spero di essere abbastanza chiaro, il succo è che con una sola classe non lo puoi fare (o meglio, lo puoi fare ma ti vai ad incasinare la vita secondo me).

Buon lavoro

SHIVA>>LuR<<
03-07-2011, 16:31
così a grandi linee secondo me hai sbagliato già dall'inizio su come hai strutturato il tutto...

Io ti direi di fare così:

classe server:
thread, crea un socketserver e si mette in ascolto (ovviamente con opportuni cicli) verso il client, ogni volta che si connette un client crea un nuovo socket che sarà associato ad una classe clientlistener.

il client listener gestirà gli stream in e out del socket quelli in ingresso li smisterà verso una coda nella classe server. La classe server avrà al suo interno un qualche thread che eseguirà i messaggi leggendoli (e togliendoli) di volta in volta dalla coda.

In questo modo nel server puoi mettere qualsiasi linkedlist, hashtable, treemap o che dir si voglia e tramite metodi dell'esecutore dei messaggi aggiornarli ogni volta.

L'unica classe che istanzi ogni volta è il clientlistener (uno per client a cui è associato un socket), perciò la classe server e la classe esecutrice dei messaggi non sono istanziate più volte e mantengono i dati.


Spero di essere abbastanza chiaro, il succo è che con una sola classe non lo puoi fare (o meglio, lo puoi fare ma ti vai ad incasinare la vita secondo me).

Buon lavoro
grazie mille
sei stato chiarissimo credo di aver capito il da farsi.