PDA

View Full Version : [JAVA] Help thread!


Villain
19-09-2011, 09:41
Ho un problema. Devo implementare i thread su un'applicazione già esistente. Devo creare un thread che inserisce un nuovo prodotto, uno che deposita e uno che eroga. Il deposito deve avanzare condizionatamente alla creazione, e l'erogazione condizionatamente al deposito.

questi sono i metodi che ho modificato

public synchronized void eroga(IDEsterno k, int quantita) throws DirittiException, ProdottoException, IDEsternoException, QuantitaException, GiacenzaInsufficienteException, InterruptedException
{
if (k==null)
{

throw new IDEsternoException("L/identificatore non deve essere nullo\n");
}
if (mappaProdotti.get(k.toString())==null)
{
System.out.println("nuovo_eroga: mi sto per fermare");
wait();
System.out.println("nuovo_eroga: mi sono svegliato");
}
if (mappaProdotti.get(k.toString())==null)
{
System.out.println("eroga: sono prima dell'ecc");
throw new ProdottoException("Prodotti " + k.toString() + " non sono presenti\n");
}
if (quantita <=0) {

System.out.println("nuovo eroga:giacenza 0: mi sto per fermare");
wait();
}
if (quantita <=0) {
System.out.println("eroga:giacenza 0: prima dell'ecc");
throw new QuantitaException ("La quantita da erogare deve essere positiva\n");
}
// if (quantita > mappaProdotti.get(k.toString()).giacenza()) {
// throw new GiacenzaInsufficienteException ("Il disponibile di " + k.toString() + " (" + giacenza(k) + ")" + " è insufficiente (" + quantita +")\n");
// }
mappaProdotti.get(k.toString()).eroga(quantita);
System.out.println("eroga: mi sto per svegliare");
notify();
}



public synchronized void deposita(IDEsterno k, int quantita) throws DirittiException, ProdottoException, IDEsternoException, QuantitaException, InterruptedException
{
if (k==null)
{

throw new IDEsternoException("L'identificatore del prodotto deve essere non nullo");
}
if (mappaProdotti.get(k.toString())==null)
{
System.out.println("nuovo deposita: mi sto per fermare");
wait();

}
if (mappaProdotti.get(k.toString())==null)
{
System.out.println("deposita: sto per lanciare l'ecc");
throw new ProdottoException("Prodotti " + k.toString() + " non sono presenti");

}
else
{
if (quantita <=0) {
throw new QuantitaException ("La quantita da depositare deve essere positiva\n");
}
else
mappaProdotti.get(k.toString()).deposita(quantita);
System.out.println("deposita: mi sto per svegliare");
notifyAll();
}
}

public synchronized void nuovoProdotto(String classeAlimento, IDEsterno k) throws DirittiException, ClasseAlimentareException, ProdottoException, IDEsternoException
{
if (CostantiClassiAlimentari.containsClasseAlimentareFinale (classeAlimento))
{
Portata p;

//Da modificare al piu presto
if (classeAlimento.equals(CostantiClassiAlimentari.Acqua))
p = new Acqua(k);
else if (classeAlimento.equals(CostantiClassiAlimentari.BriccoFrutta))
p = new BriccoFrutta(k);
else if (classeAlimento.equals(CostantiClassiAlimentari.Carne))
p = new Carne(k);
else if (classeAlimento.equals(CostantiClassiAlimentari.Dolce))
p = new Dolce(k);
else if (classeAlimento.equals(CostantiClassiAlimentari.Frutta))
p = new Frutta(k);
else if (classeAlimento.equals(CostantiClassiAlimentari.Pesce))
p = new Pesce(k);
else if (classeAlimento.equals(CostantiClassiAlimentari.Primo))
p = new Primo(k);
else if (classeAlimento.equals(CostantiClassiAlimentari.Soda))
p = new Soda(k);
else if (classeAlimento.equals(CostantiClassiAlimentari.Vino))
p = new Vino(k);
else
p = new Altro(k);
mappaProdotti.put(p, k.toString());
System.out.println("nuovo: sveglio tutti");
notifyAll();
}
else
throw new ClasseAlimentareException("\nClasse alimentare " + classeAlimento + " errata. ");

/*
Class nomeClasseObj = Class.forName(classeAlimento);
p= (Portata) nomeClasseObj.newInstance((Object) k);
*/
}

Questo è quello che mi stampa in console:
nuovo deposita: mi sto per fermare
nuovo_eroga: mi sto per fermare
nuovo: sveglio tutti
deposita: mi sto per svegliare


mi ritrovo con il prodotto inserito, e il deposito effettuato. Il problema è che il thread eroga non si sveglia -.-'
che casino ho combinato??

starfred
19-09-2011, 10:02
Ciao, cambia la eroga e sostituisci al notify con notifyAll. In ogni caso credo che il codice sia in ogni caso sbagliato.
Nella "deposita" hai due if uguali come anche nella "eroga". Credo che sia tutto sbagliato. Hai messo una notifyAll() dentro una condizione di else che non è detto che venga sempre eseguita... è un casino :D In ogni caso quando utilizzi la semantica signallAll ed hai più di due thread devi utilizzare quasi sempre il while al posto dell'if nelle condition.

Villain
19-09-2011, 10:14
Ciao, cambia la eroga e sostituisci al notify con notifyAll. In ogni caso credo che il codice sia in ogni caso sbagliato.
Nella "deposita" hai due if uguali come anche nella "eroga". Credo che sia tutto sbagliato. Hai messo una notifyAll() dentro una condizione di else che non è detto che venga sempre eseguita... è un casino :D In ogni caso quando utilizzi la semantica signallAll ed hai più di due thread devi utilizzare quasi sempre il while al posto dell'if nelle condition.

anche con notifyAll() non cambia nulla.

ho 2 if perchè se metto il wait dentro l'altro if se il thread entra la dentro, quando poi viene risvegliato si ritrova la e lancia l'eccezione. Tanto i thread li lancio con un apposito pulsante lancia thread quindi non credo sia un problema quando non li lancio (ho provato). o no?

nuovoUtente86
19-09-2011, 12:12
quello che devi fare è un classico buffer produttore-consumatore. Trovi in rete centinaia di esempio da cui partire.

Villain
19-09-2011, 12:40
quello che devi fare è un classico buffer produttore-consumatore. Trovi in rete centinaia di esempio da cui partire.

infatti avevo visto quelli, e pensavo di aver capito. Ovviamente il problema è che devo implementarli sull'applicazione già esistente, solo che non funziona.

Villain
19-09-2011, 17:22
nessuno riesce ad aiutarmi?
quando il metodo nuovoprodotto fa notifyAll() il thread sospeso su eroga non si muove di 1 riga di codice......

Villain
20-09-2011, 15:09
nessuno riesce ad aiutarmi?
quando il metodo nuovoprodotto fa notifyAll() il thread sospeso su eroga non si muove di 1 riga di codice......

bump