Newsgroup: it.comp.java
Titolo: Sincronizzazione lettura/scrittura su più file

Salve a tutti ho scritto 3 classi che hanno il compito di manipolare un 
file xml.
Ho una classe che sfrutta sax per leggere dal documento xml;
una classe che usa JDom per scrivere sul documento xml;
una classe che racchiude le altre due in modo da sincronizzare eventuali 
accessi al file xml. Quest'ultima classe è quella che viene utilizzata 
da un server concorrente e che speravo mi permettesse di realizzare la 
sincronizzazione, solo che ho problemi non indifferenti nel capire come 
realizzare questa sincronizzazione dato che io non vedo direttamente il 
file ma solo le due classi per leggere e scrivere su.
La classe che ho scritto per la sincronizzazione è questa:
import java.util.Vector;
public class ReadWriteXML {
 
	private XMLSaxReaderStat xsrs; //Classe che usa SAX per leggere file XML
	private XMLJDomWriterStat xjws;// Classe che usa JDOM per scrivere su 
file XML
	private String file;
	public final int STATISTICS_FAILED=555;
	public final int STATISTICS_SUCCESSFUL=666;
 
	public ReadWriteXML(String file){
		this.file=file;
		xsrs = new XMLSaxReaderStat(file);
		xjws = new XMLJDomWriterStat(file);
	}
 
	public synchronized void changeFile(String file){
		this.file=file;
		xsrs = new XMLSaxReaderStat(file);
		xjws = new XMLJDomWriterStat(file);
	}
 
	public synchronized int getNumberOfRequest(String method){
		Vector<String> risultati= xsrs.getData(method, "numberOfRequest");
		return Integer.parseInt(risultati.get(0));
	}
 
	public synchronized int getNumberOfFailedRequest(String method){
		Vector<String> risultati= xsrs.getData(method, "numberOfFailedRequest");
		return Integer.parseInt(risultati.get(0));
 
	}
 
	public synchronized int getNumberOfSuccessfulRequest(String method){
		Vector<String> risultati= xsrs.getData(method, 
"numberOfSuccessfulRequest");
		return Integer.parseInt(risultati.get(0));
	}
 
	public synchronized void updateStatistics(String method, int tipoAgg, 
long ttot){
		if(tipoAgg==STATISTICS_SUCCESSFUL)
		xjws.updateStatistic(method, xjws.RESPONSE_TIME, 
xjws.NUMBER_OF_SUCCESSFULL_REQUEST, (int)ttot);
		else xjws.updateStatistic(method, xjws.RESPONSE_TIME, 
xjws.NUMBER_OF_FAILED_REQUEST, (int)ttot);
	}
}
La classe deve permettere di leggere e/o scrivere sul file xml. Ho 
provato a dichiarare i metodi synchronized però non credo funzioni dato 
che l'unico metodo che scrive (updateStatistics) non ha nulla in comune 
con tutti gli altri metodi, o sbaglio?
Un'altra domanda, io ho a disposizione più file xml da cui posso leggere 
  e che posso scrivere in contemporanea ma come ho scritto la classe non 
credo che venga gestita anche questa eventualità dato che forse sarebbe 
meglio inizializzare in ogni metodo le classi per la lettura e la 
scrittura di un file o sbaglio?
Come potrei sincronizzare l'intera classe in modo che vi si acceda uno 
alla volta?
Grazie a tutti, ciao ciao.

 file ma solo le due classi per leggere e scrivere su.
male.
io farei:
- 1 classe che fa l'i/o vero e proprio sul file. questa classe avra'
un metodo read e un metodo write (synchronized entrambi).
- n classi che useranno i metodi write e read della classe sopra per
leggere e scrivere sul file.
Ciao Jack

Jack ha scritto:

Ciao, ho modificato un pò tutto ed ho un'unica classe che legge e scrive 
su un file xml tramite jdom in questo modo:
public class XMLJDomStat {
 
	private File fileXML;
	private Document doc;
	private FileOutputStream fouts;
	private SAXBuilder sb;
	private final String methodTag="method";
	private final String numberOfRequest="numberOfRequest";
	private final String responseTime="responseTime";
	private final String numberOfSuccessfulRequest = 
"numberOfSuccessfulRequest";
	private final String numberOfFailedRequest = "numberOfFailedRequest";
	private Attribute attributo;
	public final int NUMBER_OF_SUCCESSFULL_REQUEST=20;
	public final int NUMBER_OF_FAILED_REQUEST=30;
	public final int THROUGHPUT=40;
	public final int RESPONSE_TIME=50;
 
	public XMLJDomStat(String file){
 
		fileXML = new File(file);
 
		sb = new SAXBuilder();
 
	}
 
	private void openFile(){
		try {
			if(!fileXML.exists()) {
				PrintStream Output = new PrintStream(fileXML);
				Output.println("<?xml version=\"1.0\" 
encoding=\"UTF-8\"?>\n"+"<service>\n"+"</service>\n");
			}
 
			doc = sb.build(fileXML);
		} catch (JDOMException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
 
 
 
	private void writeFile(){
		XMLOutputter xmlOutputter = new XMLOutputter();
		 xmlOutputter.setFormat(Format.getPrettyFormat());
 
		 try {
			fouts = new FileOutputStream (fileXML);
 
			xmlOutputter.output(doc, fouts);
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
 
 
 
	private List<Element> getMethodModified(String name, String stat, 
Element root){
		List<Element> metodi = root.getChildren(methodTag);
 
		for(int i=0; i< metodi.size(); i++){
			if(metodi.get(i).getAttributeValue("name").equalsIgnoreCase(name)){
				return metodi.get(i).getChildren(stat);
			}
 
		}
		return null;
	}
 
	private void addMethod(String methodName, Element root){
		System.out.println("Metodo da aggiungere:"+methodName);
		Element method = new Element("method");
		method.setAttribute(new Attribute("name", methodName));
		for(int i=0; i<10; i++){
			Element responseTime = new Element("responseTime");
			Attribute value = new Attribute("value", "0");
			responseTime.setAttribute(value);
			Attribute ch;
			if(i==0)
				ch = new Attribute("ch", "yes");
			else ch = new Attribute("ch", "no");
			responseTime.setAttribute(ch);
 
			method.addContent(responseTime);
		}
 
		Element nrRequest= new Element("numberOfRequest");
		//Attribute valueNeReq = new Attribute("value", "0");
		nrRequest.setAttribute(new Attribute("value","0"));
		method.addContent(nrRequest);
 
		Element nrRequestSucc=  new Element("numberOfSuccessfulRequest");
		nrRequestSucc.setAttribute(new Attribute("value","0"));
		method.addContent(nrRequestSucc);
 
		Element nrRequestFail=  new Element("numberOfFailedRequest");
		nrRequestFail.setAttribute(new Attribute("value","0"));
		method.addContent(nrRequestFail);
 
		root.addContent(method);
 
		writeFile();
 
	}
 
	public Vector<String> getData(String methodName, String elemento){
		openFile();
		Element root = doc.getRootElement();
		Vector<String> found = new Vector<String>();
		List<Element> nrs = getMethodModified(methodName, elemento, root);	
 
		if(nrs!=null)
		for(int i=0; i< nrs.size(); i++){
			found.add(nrs.get(i).getAttributeValue("value"));
		}
		else{
			addMethod(methodName, root);
			System.out.println("Inserire il pezzo per aggiungere le statistiche 
al file xml:-)");
		}
 
		return found;
	}
 
	public void updateStatistic(String methodName, int timeResponse, int 
typeRequest, int response){
		int statistiche[] = new int [2];
		statistiche[0]=typeRequest;
		statistiche[1]=timeResponse;
 
		openFile();
		Element root = doc.getRootElement();
 
 
		for(int i=0; i<statistiche.length; i++){
 
 
			switch (statistiche[i]) {
 
			case NUMBER_OF_SUCCESSFULL_REQUEST:
				//System.out.println("Numero di richieste eseguite con successo");
				List<Element> nrs = getMethodModified(methodName, 
numberOfSuccessfulRequest, root);
				String values = nrs.get(0).getAttributeValue("value");
				int nrInts = Integer.parseInt(values);
				nrInts++;
				nrs.get(0).setAttribute("value", nrInts+"");
				List<Element> nr = getMethodModified(methodName, 
this.numberOfRequest, root);
				String value = nr.get(0).getAttributeValue("value");
				int nrInt = Integer.parseInt(value);
				nrInt++;
				nr.get(0).setAttribute("value", nrInt+"");
 
				break;
 
			case NUMBER_OF_FAILED_REQUEST:
 
				List<Element> nrf = getMethodModified(methodName, 
this.numberOfFailedRequest, root);
				String valuef = nrf.get(0).getAttributeValue("value");
				int nrIntf = Integer.parseInt(valuef);
				nrIntf++;
				nrf.get(0).setAttribute("value", nrIntf+"");
				List<Element> nrr = getMethodModified(methodName, 
this.numberOfRequest, root);
				String valuess = nrr.get(0).getAttributeValue("value");
				int nrIntss = Integer.parseInt(valuess);
				nrIntss++;
				nrr.get(0).setAttribute("value", nrIntss+"");
 
				break;
 
 
			case RESPONSE_TIME:
				List<Element> responseT = getMethodModified(methodName, 
responseTime, root);
 
				for(int j=0; j<responseT.size(); j++){
					if(responseT.get(j).getAttributeValue("ch").equalsIgnoreCase("yes")){
 
						attributo = responseT.get(j).getAttribute("value");
					    attributo.setValue(response+"");
						attributo = responseT.get(j).getAttribute("ch");
						attributo.setValue("no");
						j = (j+1) % 10;
						attributo = responseT.get(j).getAttribute("ch");
						attributo.setValue("yes");
						break;
					}
				}
 
				break;
			default:
				break;
			}//fine switch
 
 
		}//fine for
		writeFile();		
	}
}
Per sincronizzarla mi basterebbe sincronizzare tutti i metodi?
Grazie, ciao ciao.


tutti i metodi che accedono al file.
Ciao Jack


Ciao io ho sincronizzato tutti i metodi per sicurezza :-). In ogni caso 
tutti i vetodi mi vanno a leggere dal file.
Un'altra domanda non mi è stato possibile dichiarare synchronized il 
costruttore però ho potuto dichiare un blocco:
synchronized (this){
//lavoro costruttore
}
Va bene lo stesso?
Grazie, ciao ciao.

 Grazie, ciao ciao.
allora fossi in te andrei a guardare cosa fa synchronized esattamente.
<
http://java.sun.com/docs/books/tutorial/essential/concurrency/
syncmeth.html>
Ciao Jack