PDA

View Full Version : dubbi sui Thread [JAVA]


Squiddi
22-05-2014, 19:48
Salve a tutti ragazzi, dovrei fare un esercizio in Java ma ho avuto qualche problema in qualche passaggio, innanzitutto vi spiego cosa deve fare il mio programma, dato un array di 100000 elementi devo generare un valore casuale in quell' intervallo e devo fare tre thread (non so come separarli), uno che ricerca da inizio alla fine, un altro che ricerca dalla fine all' inizio e un terzo thread che ricerca da metà spostandosi avanti di uno e indietro di uno, poi avanti di due e poi indietro di due, ecc... Poi appena uno dei tre thread trova il valore generato al lancio del programma deve interrompere gli altri due.

Allora, i miei problemi sono che prima di tutto non riesco a fare il terzo thread che ricerca partendo da metà, cioè deve partire dal centro, poi cercare il valore sopra la metà, poi il valore sotto la metà e così via (per esempio se è da 1 a 100 deve cercare da 50, poi 51, poi 49, poi 52, poi 48, ecc...).
Poi l' altro mio problema è che quando uno dei tre thread di ricerca ha finito deve interrompere anche gli altri due stampando che ha finito, come faccio ?
Intando ecco il mio condice che ho scritto finora:


///********** CLASSE RICERCA *******///
ublic class Ricerca extends java.lang.Thread {

/**
* indice minimo di ricerca
*/
int imin;

/**
* indice massimo di ricerca
*/
int imax;

/**
* array che contiene gli elementi da verificare
*/
int v[];

/**
* valore da ricercare
*/
int val;

/**
* Costruttore generale
* @param imin indice minimo
* @param imax indice massimo
* @param v vettore
* @param val valore da cercare
*/
public Ricerca(int imin, int imax, int[] v, int val) {
super();
this.imin = imin;
this.imax = imax;
this.v = v;
this.val = val;
}

/**
* visualizza gli indici degli elementi presenti in v con valore val
*/
public void run() {
Thread t = Thread.currentThread();
t.setName("Ricerca da "+imin+" a "+imax);
for(int i=imin;i<=imax;i++)
if (v[i]==val)
{
System.out.println(t.getName()+" indice "+i);
try {
sleep((long)(Math.random() * 1000)); //attesa casuale
} catch (InterruptedException e) {
e.printStackTrace();
}
}

System.out.println(t.getName()+" Finito");
}
}



///***************CLASSE MAIN**********************///

public class Main {
public static void main(String[] args) {
final int dimArray = 1000000; //dimensione array
final int dimValori = 10000; //valori casuali fra 1 e dimValori
int vett[] = new int[dimArray];
int valore;
// caricamento array con valori casuali
for (int i=0;i<dimArray;i++)
vett[i] = (int) (Math.random() * dimValori);
valore = (int) (Math.random() * dimValori);
System.out.println("Valore da cercare: "+valore);
// imposta la classe per la ricerca nella prima parte dell'array
Ricerca thr1 = new Ricerca(0, dimArray/2-1, vett, valore);
// imposta la classe per la ricerca nella seconda classe dell'array
Ricerca thr2 = new Ricerca(dimArray/2,dimArray-1, vett, valore);
thr1.start();
thr2.start();
System.out.println("Thread partiti");
while(thr1.isAlive()||thr2.isAlive()); // attesa
System.out.println("Entrambe i Thread sono terminati");
}

}



Grazie mille in anticipo :)

Squiddi
23-05-2014, 13:53
Rispondete per favore è urgente

sottovento
23-05-2014, 14:30
Ho modificato un po' il tuo codice e messo nel package com.sottovento SOLO per motivi di debug. Non voglio impossessarmi del tuo codice, non preoccuparti ;)

alcune parole:
1 - il ciclo che facevi nel main() bruciava la cpu per nulla. Meglio delle join();
2 - per sincronizzare i thread utilizzo una AtomicBoolean, cioe' una semplice variabile booleana. Questo semplifica molto il codice e garantisce comunque che la variabile sia modificata atomicamente;
3 - una sola classe di ricerca e' sufficiente, basta aggiungere un paio di parametri. Se c'e' qualcosa che ti suona strano, chiedi pure ma non sono sicuro di poter rispondere: qui nel deserto Internet funziona raramente;
4 - ho aggiunto il nome dei thread cosi' da semplificare il debug e i messaggi di trace nel caso abbia bisogno di cercare errori




package com.sottovento;

import java.util.concurrent.atomic.AtomicBoolean;

/*
* @author squiddi
*/
public class Main
{
/**
* Everything starts here
* @param args command line arguments
*/
public static void main(String[] args)
{
final int dimArray = 1000000; //dimensione array
final int dimValori = 10000; //valori casuali fra 1 e dimValori
int vett[] = new int[dimArray];

int toBeFound;
// caricamento array con valori casuali
for (int i=0;i<dimArray;i++)
vett[i] = (int) (Math.random() * dimValori);

toBeFound = (int) (Math.random() * dimValori);
System.out.println("Valore da cercare: "+toBeFound);

AtomicBoolean done = new AtomicBoolean(false); /* Questo viene modificato atomicamente, quindi non c'e' bisogno di sincronizzarne l'accesso */

// Ricerca dall'inizio alla fine
int startIndex = 0;
int endIndex = dimArray-1;
int step = 1;
boolean alternate = false;
String threadName = "Thread_ascendente";
Ricerca thr1 = new Ricerca(threadName, done, startIndex, endIndex, step, alternate, vett, toBeFound);

// Ricerca dalla fine all'inizio
startIndex = dimArray-1;
endIndex = 0;
step = -1;
alternate = false;
threadName = "Thread_discendente";
Ricerca thr2 = new Ricerca(threadName, done, startIndex,endIndex, step, alternate, vett, toBeFound);

// Ricerca allontanandosi dalla meta'
startIndex = dimArray/2;
endIndex = 0;
step = 1;
alternate = true;
threadName = "Thread_matto";
Ricerca thr3 = new Ricerca(threadName, done, startIndex, endIndex, step, alternate, vett, toBeFound);

thr1.start();
thr2.start();
thr3.start();

System.out.println("Thread partiti");
try
{
thr1.join(); /* wait for thr1 completion */
thr2.join(); /* wait for thr2 completion */
thr3.join(); /* wait for thr3 completion */
int index1 = thr1.getFoundIndex();
int index2 = thr2.getFoundIndex();
int index3 = thr3.getFoundIndex();
if (index1 >= 0)
System.out.println ("Thread \"" + thr1.getThreadName() + "\" has found the element in position " + index1);
if (index2 >= 0)
System.out.println ("Thread \"" + thr2.getThreadName() + "\" has found the element in position " + index2);
if (index3 >= 0)
System.out.println ("Thread \"" + thr3.getThreadName() + "\" has found the element in position " + index3);

}
catch (InterruptedException e)
{
System.out.println ("Applicazione interrotta");
}
System.out.println("Tutti i thread sono terminati");
}
}

class Ricerca extends Thread
{
private final int startIndex;
private final int endIndex;
private final int step;
private final boolean alternate;
private final int vect[];
private final int toBeFound;
private final AtomicBoolean done;
private final String threadName;

/* Risultati da ritornare al chiamante */
private int foundIndex; /* Indice contenente l'elemento trovato, oppure -1 */

public Ricerca(String threadName, AtomicBoolean done, int startIndex, int endIndex, int step, boolean alternate, int[] vect, int toBeFound)
{
this.threadName = threadName;
this.done = done;
this.startIndex = startIndex;
this.endIndex = endIndex;
this.step = step;
this.alternate = alternate;
this.vect = vect;
this.toBeFound = toBeFound;
this.foundIndex = -1;
}

public int getFoundIndex()
{
return foundIndex;
}

public String getThreadName()
{
return threadName;
}

/**
* visualizza gli indici degli elementi presenti in vect con valore val
*/
@Override
public void run()
{
int index = 0;
while (!done.get() && (startIndex + index) >= 0 && (startIndex + index) < vect.length)
{
if (vect[startIndex + index] == toBeFound)
{ /* Element found. All thread should stop their process */
foundIndex = startIndex + index;
done.set(true); /* This makes all threads stopping */
}
else
{
if (alternate)
{
index = -index;
if (index >= 0)
index += step;
}
else
index += step;
}
}
}
}

Squiddi
23-05-2014, 15:22
Grazie mille :)
Ho provato il tuo codice è corretto penso, ma l' unico problema è che quando ricerco un valore devono saltare fuori tutte le scritte dei thread che ricercano il l'elemento, cioè così:
Thread 1 sta cercando è al valore 000
Thread 1 sta cercando è al valore 001
Thread 1 sta cercando è al valore 002

E così continua finchè uno dei tre thread non lo trova, grazie in anticipo :) Sei molto gentile :)

sottovento
23-05-2014, 15:37
Grazie mille :)
Ho provato il tuo codice è corretto penso, ma l' unico problema è che quando ricerco un valore devono saltare fuori tutte le scritte dei thread che ricercano il l'elemento, cioè così:
Thread 1 sta cercando è al valore 000
Thread 1 sta cercando è al valore 001
Thread 1 sta cercando è al valore 002

E così continua finchè uno dei tre thread non lo trova, grazie in anticipo :) Sei molto gentile :)
Non mi sembra un problema: ho assegnato un nome ad ogni thread per questo motivo.
Ora sono un po' impegnato. Puoi provarci e farmi sapere se hai problemi.

Ciau