PDA

View Full Version : [JAVA] Multithread senza vantaggi


Lim
23-08-2010, 11:52
Sto sviluppando un software che potrebbe beneficiare dei vantaggi del multithread, ma non noto vantaggi tra le due implementazioni.

Ho provato, allora, a scrivere una semplice classe per confrontare i tempi di esecuzione tra un'implementazione monotrhead ed una multithread, ancora nessun beneficio nella multithread.

Forse sbaglio qualcosa? è la JVM che abbatte le prestazioni del multithread? (in C# l'uso dei thread era sempre stato vantaggioso...)


Ho provato queste semplici righe di codice:


[...]
System.out.println("Primo ciclo");
for (int i=0; i< size; i++){
System.out.println("passo "+i);
}

System.out.println("Secondo ciclo");
for (int i=0; i< size; i++){
System.out.println("passo "+i);
}



Ho cronometrato l'esecuzione con System.currentTimeMillis()

Poi ho inserito i due cicli in due thread diversi e li ho lanciati, più o meno ci mette lo stesso tempo...


Thread t1;
t1=new Thread1(size);


Thread t2;
t2=new Thread2(size);

t1.start();
t2.start();


Ovviamente, nelle classi Thread1 e Thread2 ho messo il singolo ciclo for...
Dove sbaglio? :help:

banryu79
23-08-2010, 13:51
Ovviamente, nelle classi Thread1 e Thread2 ho messo il singolo ciclo for...
Dove sbaglio? :help:
L'errore non ha niente a che vedere con il multithreading in senso stretto: in entrambe le versioni (single-threaded VS multi-threaded) stai eseguendo per 2*'size' volte l'operazione println() sull'ogetto System.out (il PrintWriter associato allo "standard output").

Per quanto la classe PrintWriter sia thread-safe (i metodi tipo write() si sincronizzano con un lock intrinseco sul monitor dell'oggetto stesso) una scrittura su di essa è comuque bloccante: 2*'size' scritture eseguite in un unico thread o da due thread diversi ci mettono all'incirca lo stesso tempo.

P.S.: se devi avere a che fare con il multithreading nella tua applicazione ti consiglio questa pagina (http://forums.sun.com/ann.jspa?annID=9) come puto di partenza per cercare informazioni utili.
Anche se hai già esperienza di programmazione in ambito multithreded in C#, farlo in Java non sarà giocoforza la stessa cosa, e non per una semplice questione di linguaggio, quanto di piattaforma (il bytecode Java è agnostico rispetto il sistema operativo, e questo implica un tot di concetti nuovi e/o diversi). Se vuoi le specifiche complete, consulta il memory model (http://en.wikipedia.org/wiki/Java_Memory_Model).

Lim
23-08-2010, 14:02
L'errore non ha niente a che vedere con il multithreading in senso stretto: in entrambe le versioni (single-threaded VS multi-threaded) stai eseguendo per 2*'size' volte l'operazione println() sull'ogetto System.out (il PrintWriter associato allo "standard output").

Per quanto la classe PrintWriter sia thread-safe (i metodi tipo write() si sincronizzano con un lock intrinseco sul monitor dell'oggetto stesso) una scrittura su di essa è comuque bloccante: 2*'size' scritture eseguite in un unico thread o da due thread diversi ci mettono all'incirca lo stesso tempo.



Ti ringrazio per la risposta.
In effetti ero arrivato alla stessa conclusione riguardo al System.out, così ho provato a non eseguire nulla all'interno dei cicli, il tempo di esecuzione si riduce drasticamente (circa 1 secondo per ogni ciclo for), ma rimane immutato il tempo di esecuzione globale sia del single-thread che del multi-thread.

Ora approfondisco con il link che mi hai fornito...

banryu79
23-08-2010, 14:13
In effetti ero arrivato alla stessa conclusione riguardo al System.out, così ho provato a non eseguire nulla all'interno dei cicli...

In questo caso il compilatore è abbastanza "furbo" è si accorge che non c'è niente da fare, dunque non cicla proprio ;)

P.S.:
Leggendo tra le righe signifca che se vuoi applicare il multi-threading con successo devi prima capire se ti può essere effettivamente utile, dunque individuare su che porzione/operazione/task specifico dell'applicazione pensi possa essere opportuno utilizzarlo.
Intanto chiediti perchè senti la neccessità del multithreading: hai un collo di bottiglia prestazionale?
Se sì, hai già provato a fare del profiling sull'applicazione, per individuare con esattezza il collo di bottiglia?

Lim
23-08-2010, 14:26
In questo caso il compilatore è abbastanza "furbo" è si accorge che non c'è niente da fare, dunque non cicla proprio ;)

P.S.:
Leggendo tra le righe signifca che se vuoi applicare il multi-threading con successo devi prima capire se ti può essere effettivamente utile, dunque individuare su che porzione/operazione/task specifico dell'applicazione pensi possa essere opportuno utilizzarlo.
Intanto chiediti perchè senti la neccessità del multithreading: hai un collo di bottiglia prestazionale?
Se sì, hai già provato a fare del profiling sull'applicazione, per individuare con esattezza il collo di bottiglia?

Ah ecco, il compilatore fa il "furbo", allora provo a fargli fare qualche calcolo aritmetico...
Non ho fatto il profiling, ma ho varie sezioni da ottimizzare, prima fra tutte, il controllo incrociato di un elevato numero di elementi.
Ho una lista composta da migliaia di oggetti e vorrei verificare, due a due, se questi soddisfano alcune condizioni.
Pensavo di utilizzare alcuni thread per eseguire più confronti contemporaneamente...

banryu79
23-08-2010, 14:38
Ah ecco, il compilatore fa il "furbo", allora provo a fargli fare qualche calcolo aritmetico...
Non ho fatto il profiling...

Allora ti consiglio caldamente di farlo, prima di trarre le conclusioni che hai tratto (per quanto leggittime), parlo per esperienza diretta :fagiano:

clockover
24-08-2010, 00:30
Mi intrometto per consigliare di dare uno sguardo al package java.util.concurrent (http://download.oracle.com/javase/tutorial/essential/concurrency/highlevel.html)....;)