PDA

View Full Version : [Java] Aiuto con i Thread


aeroxr1
05-09-2010, 11:36
ciao,
ho dei problemi a capire il funzionamento dei thread e dei metodi con esso più usati wait(), notifyAll(), e l'attributo synchronized .
Per avere un esempio su cui potervi fare domande vi posto un esercizio fatto dal mio professore :

(la classe console è una classe per l'ingresso e uscita )

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

class Giro extends Thread {
private String parola;
private Giro next;
private int cicli;

public Giro(int cicli, String parola) {
this.parola = parola;
this.cicli = cicli;
}

public void setNext(Giro next) {
this.next = next;
}

public synchronized void aspetta() {
try {
while (!interrupted())
wait();
} catch(InterruptedException e) {}
}

public void vai() {
interrupt();
}

public void run() {
for (int i = 0; i < cicli; i++) {
aspetta();
Console.scriviStringa(parola);
next.vai();
}
}
}

class Esa {
public void fai(String nomefile) throws IOException {
Scanner sc = new Scanner(new BufferedReader(new FileReader(nomefile)));
Giro g = null, primo = null;
try {
int cicli = sc.nextInt();
Giro prev = null;
for (;;) {
String parola = sc.next();
g = new Giro(cicli, parola);
g.start();
if (prev != null)
prev.setNext(g);
prev = g;
if (primo == null)
primo = g;
}
}
catch (Exception e) {}
finally {
sc.close();
}

if (primo != null) {
g.setNext(primo);
primo.vai();
}
}
}


import java.io.*;
class Pesa {
public static void main(String[] args) throws IOException {
String[] parole = { "primo", "secondo", "terzo" };
PrintWriter p = new PrintWriter(new FileWriter("dati.txt"));
p.println(3);
p.println("uno due tre");
p.close();
Esa esa = new Esa();
esa.fai("dati.txt");
}
}


l'output è :

uno
due
tre
uno
due
tre
uno
due
tre


ecco le mie domande :
1- com'è possibile che ci sia il wait() nel metodo aspetta senza che da nessun'altra parte vi sia un notify() o notifyAll() ? cioè facendo cosi non si bloccano tutti i thread ?

2- poi non capisco una cosa generale dei Thread . Nelle due righe che ho scritto in rosso , vi è la creazione di un oggetto g e l'avvio del relativo thread con start() . Ecco a questo punto si avvia il thread , ma questo si bloccherà al primo wait che trova e va nella lista dei thread bloccati , e io mi chiedo : come fanno a partire gli altri Thread ?

Il main resta in esecuzione nonostante partano i Thread ?


Cavolo non ciò capito nulla ... Spero possiate darmi una mano ! :)

tuccio`
05-09-2010, 11:55
http://download.oracle.com/javase/1.4.2/docs/api/java/lang/Thread.html#interrupt%28%29

If this thread is blocked in an invocation of the wait(), wait(long), or wait(long, int) methods of the Object class, or of the join(), join(long), join(long, int), sleep(long), or sleep(long, int), methods of this class, then its interrupt status will be cleared and it will receive an InterruptedException.

banryu79
05-09-2010, 12:08
Tenendo in considerazione le informazioni che ti ha indicato tuccio, qua sopra, prendi carta&matita e prova a simulare l'esecuzione passo-passo del programma.

Suggerimento: il punto chiave è questo pezzo di codice del metodo fai() nella classe Esa, che si trova dopo il ciclo:

...
if (primo != null) {
g.setNext(primo);
primo.vai();
}
...

aeroxr1
05-09-2010, 18:55
Tenendo in considerazione le informazioni che ti ha indicato tuccio, qua sopra, prendi carta&matita e prova a simulare l'esecuzione passo-passo del programma.

Suggerimento: il punto chiave è questo pezzo di codice del metodo fai() nella classe Esa, che si trova dopo il ciclo:

...
if (primo != null) {
g.setNext(primo);
primo.vai();
}
...


grazie per le dritte ! salverò il sito tra i preferiti . DI queste cose sul libro consigliato dal professore per lo studio non c'era scritto niente -.-"

comunque ora provo a prendere carta e penna , però prima di tutto ho un dubbio .
Ho provato diverse volte a simulare i risultati di programmi dove ci sono le chiamate dei thread , ma non mi è molto chiara una cosa :

mettiamo che il main chiami un thread e lo avvi con il metodo start()
dopo lo start() ci siano un paio di operazioni di stampa a video :

pippo.start();
Console.scriviStringa("A");
Console.scriviStringa("B");

e nel run ci sia un altra stampa a video e sia dopo lo start()

Consol.scriviStringa(papero);
console.scriviStringa (cappello);


cosa viene stampato prima e perchè ? non capisco il criterio di esecuzione del Thread . Cioè è un processo eseguito "parallelamente" al main ?


So che vi faccio tante domande , ma a me non riesce imparare le cose meccaniche e quindi chiedo a voi sperando di non rompervi troppo :)

tuccio`
05-09-2010, 19:03
se non ci sono meccanismi di sincronizzazione non puoi fare nessuna assunzione sullo scheduling

aeroxr1
05-09-2010, 19:23
se non ci sono meccanismi di sincronizzazione non puoi fare nessuna assunzione sullo scheduling

sul programma invece che ho postato , presumo quindi possiamo fare assunzioni giusto ? ;)

Sto provando a vedere i valori che stampa , però mi fermo al solito punto .

Dal sito che mi avete linkato ho capito che :
se arriva un interruzione su un thread che sta dormendo a causa di uno sleep() o è bloccato a causa di un wait() , viene levato lo stato d'interruzione e viene lanciata un eccezione.

FIn qui ci sono ? :)

Vi spiego passo passo come ragiono , cosi magari mi dite dove sbaglio :stordita: :

tramite questo ciclo , fino a quando nel file ci saranno parole verrà creato un thread per ogni parola e quando le parole finiranno verrà lanciata l'eccezione e uscirà dal for . I thread si bloccano tutti nello stato di wait() , perchè non vi sono interruzioni lanciate per ora giusto ? ;)

for (;;) {
String parola = sc.next();
g = new Giro(cicli, parola);
g.start();
if (prev != null)
prev.setNext(g);
prev = g;
if (primo == null)
primo = g;
}

poi chiama primo.vai , questo crea un eccezione e dopo continua l'esecuzione del run , stampa la parola e poi procede con il thread successivo .

Il problema è che per me dovrebbe venir stampato :
uno
due
tre

ma non

uno
due
tre
uno
due
tre
uno
due
tre

Dove sbaglio ?

tuccio`
05-09-2010, 20:55
il terzo alla fine della sua esecuzione avvia il suo "next", che è settato così:


if (primo != null) {
g.setNext(primo);
primo.vai();
}


perché g quando arriva a questo punto è l'ultimo..

il terzo thread quindi fa quello che fanno tutti gli altri, dopo aver scritto avvia il proprio next, quindi non c'è una fine a questo ciclo

aeroxr1
06-09-2010, 00:16
il terzo alla fine della sua esecuzione avvia il suo "next", che è settato così:


if (primo != null) {
g.setNext(primo);
primo.vai();
}


perché g quando arriva a questo punto è l'ultimo..

il terzo thread quindi fa quello che fanno tutti gli altri, dopo aver scritto avvia il proprio next, quindi non c'è una fine a questo ciclo

allora vengono attivati 3 thread e vengono avviati uno per uno mano mano che vengono creati con g.start() . A questo punto si bloccano tutti in attesa di un interruzione .
Manda l'interruzione al primo e il primo si sblocca e quindi ritorna al run , a questo punto stampa la parola e fa next.vai() sbloccando il secondo thread che a sua volta stamperà 2 e sbloccherà il terzo thread che stamperà 3 .



public synchronized void aspetta() {
try {
while (!interrupted())
wait();
} catch(InterruptedException e) {}
}




public void run() {
for (int i = 0; i < cicli; i++) {
aspetta();
Console.scriviStringa(parola);
next.vai();
}


QUando faccio next.vai() allora riparte tutto il run del thread next ???
Se si perchè ?
E come mai allora mi fa 3 stampe di uno due tre e non infinite ?

Che scatole , vorrei riuscire a capire il funzionamento dei thread a modo , ma a quanto pare non è tanto semplice :(

banryu79
06-09-2010, 08:26
QUando faccio next.vai() allora riparte tutto il run del thread next ???
Se si perchè ?
E come mai allora mi fa 3 stampe di uno due tre e non infinite ?

Attento che, a concentrarsi troppo su una sola parte del codice a volte si rischia di lasciarsi sfuggire qualcosa.
Ad esempio il fatto che un Giro, ha un membro 'cicli' che viene usato nella sua implementazione del metodo 'run' appunto per controllare per quante volte ripetere il comportamento di "attendi-stampaStringa-avviaProssimoThread".

Se poi esamini la classe Pesa vedrai che il file di input creato è questo:

3
uno due tre


Il che significa che vengono create 3 istanze di Giro, ognuna inizializzata con il membro 'cicli' che vale 3, la prima con la stringa "uno", la seconda con la stringa "due" e l'ultima, la terza, con la stringa "tre".

Ora forse ti è più chiaro cosa accade.
Quando ti suggerivo di provare con carta&matita a simulare passo-passo il codice che hai postato, intendevo tutto il codice, non solo una parte ;)

aeroxr1
06-09-2010, 09:08
Attento che, a concentrarsi troppo su una sola parte del codice a volte si rischia di lasciarsi sfuggire qualcosa.
Ad esempio il fatto che un Giro, ha un membro 'cicli' che viene usato nella sua implementazione del metodo 'run' appunto per controllare per quante volte ripetere il comportamento di "attendi-stampaStringa-avviaProssimoThread".

Se poi esamini la classe Pesa vedrai che il file di input creato è questo:

3
uno due tre


Il che significa che vengono create 3 istanze di Giro, ognuna inizializzata con il membro 'cicli' che vale 3, la prima con la stringa "uno", la seconda con la stringa "due" e l'ultima, la terza, con la stringa "tre".

Ora forse ti è più chiaro cosa accade.
Quando ti suggerivo di provare con carta&matita a simulare passo-passo il codice che hai postato, intendevo tutto il codice, non solo una parte ;)

l'ho fatto con carta e matita , su tutto il codice eppure sui thread mi sfugge sempre qualcosa . ORa riprovo .

Niente non mi riesce ancora .

Il fatto che in cicli ci sia 3 lo sapevo già , solo che non capisco come proceda l'esecuzione del Thread .

Una volta che arriva l'interrupt ogni singolo thread parte dal punto in cui era rimasto bloccato ( grazie al fatto che arriva un interrupt nel momento in cui il thread è bloccato con wait() e quindi genera l'eccezione e esce dalla funzione aspetta() e quindi esegue il resto del run() ) e quindi fa le operazioni dopo aspetta() :

public void run() {
for (int i = 0; i < cicli; i++) {
aspetta();
Console.scriviStringa(parola);
next.vai();
}

cicli vale 3 e fin qui ci siamo , poi thread uno stampa Uno e con next.vai() "sblocca" il secondo e il terzo e quindi viene stampato
Uno
Due
Tre

Ora si ritorna nuovamente al primo , però non capisco cosa faccia di preciso a questo punto :

abbiamo rimandato un interrupt al primo , però la funzione aspetta() non capisco perchè venga nuovamente richiamata , cioè non capisco come faccia a sapere il compilatore che dopo l'ultimo vai si riparte da aspetta() .

Forse ho capito , il motivo è :
mentre faccio next.vai() , si avvia si il thread due ma il thread uno , parallelamente , continua il ciclo e ripete nuovamente aspetta() , e si riferma in attesa di un altro interrupt che gli arriva solamente quando il terzo thread rifarà next.vai() . ?

Ho capito le parti in grassetto o ho preso fischi per fiaschi ? ;)

Se ho capito , mi dite un ultima cosa ?

Qui aspetta è synchronized . Se esso non lo fosse , che cambierebbe ? Perchè io so che se è synchronized più thread non possono eseguire la stessa funzione contemporaneamente , però in questo caso non potrebbe anche venir omesso il synchonized ?

banryu79
06-09-2010, 09:58
Sì, la svista era dovuta al fatto di non esserti reso conto che il metodo 'run' dei thread che implementa la sequenza di attesa-stampaStringa-avviaProssimo è contenuta in un ciclo :)

Se matita&carta tante volte sono utili, ma richiedono "troppo" tempo, puoi provare prima a usare il loro equivalente elettronico: stampare sullo standard output ;)

Ad esempio, prova a copiare e eseguire questa versione modificata del tuo codice, e ad esaminarne l'output (puoi sostituire i System.out.println() con le chiamate alla tua classe Consolle):

package concurrent;

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

class Giro extends Thread
{
private String parola;
private Giro next;
private int cicli;

public Giro(int cicli, String parola) {
this.parola = parola;
this.cicli = cicli;
}

public void setNext(Giro next) {
this.next = next;
}

public synchronized void aspetta() {
try {
while (!interrupted())
wait();
} catch(InterruptedException e) {}
}

public void vai() {
interrupt();
}

@Override
public void run() {
System.out.println(this.getName() + " inizio esecuzione.");
System.out.println(this.getName() + " aspetta, ciclo 0");
for (int i = 0; i < cicli; i++) {
aspetta();
System.out.println(this.getName() + " run again, ciclo " + i);
System.out.println(parola);
System.out.println(this.getName() + " lancia prossimo thread, ciclo " + i);
System.out.println(this.getName() + " aspetta, ciclo " + (i+1));
next.vai();
}
System.out.println(this.getName() + " fine esecuzione.");
}
}

class Esa
{
public void fai(String nomefile) throws IOException {
Scanner sc = new Scanner(new BufferedReader(new FileReader(nomefile)));
Giro g = null, primo = null;
try {
int cicli = sc.nextInt();
Giro prev = null;
int id = 1;
for (;;) {
String parola = sc.next();
g = new Giro(cicli, parola);
g.setName("Thread-"+id);
id = id+1;
g.start();
if (prev != null)
prev.setNext(g);
prev = g;
if (primo == null)
primo = g;
}
}
catch (Exception e) {}
finally {
sc.close();
}

if (primo != null) {
g.setNext(primo);
primo.vai();
}
}
}


ti ho colorato le modifiche, così le puoi replicare sul tuo codice.

aeroxr1
06-09-2010, 10:02
Sì, la svista era dovuta al fatto di non esserti reso conto che il metodo 'run' dei thread che implementa la sequenza di attesa-stampaStringa-avviaProssimo è contenuta in un ciclo :)

Se matita&carta tante volte sono utili, ma richiedono "troppo" tempo, puoi provare prima a usare il loro equivalente elettronico: stampare sullo standard output ;)

Ad esempio, prova a copiare e eseguire questa versione modificata del tuo codice, e ad esaminarne l'output (puoi sostituire i System.out.println() con le chiamate alla tua classe Consolle):

package concurrent;

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

class Giro extends Thread
{
private String parola;
private Giro next;
private int cicli;

public Giro(int cicli, String parola) {
this.parola = parola;
this.cicli = cicli;
}

public void setNext(Giro next) {
this.next = next;
}

public synchronized void aspetta() {
try {
while (!interrupted())
wait();
} catch(InterruptedException e) {}
}

public void vai() {
interrupt();
}

@Override
public void run() {
System.out.println(this.getName() + " inizio esecuzione.");
System.out.println(this.getName() + " aspetta, ciclo 0");
for (int i = 0; i < cicli; i++) {
aspetta();
System.out.println(this.getName() + " run again, ciclo " + i);
System.out.println(parola);
System.out.println(this.getName() + " lancia prossimo thread, ciclo " + i);
System.out.println(this.getName() + " aspetta, ciclo " + (i+1));
next.vai();
}
System.out.println(this.getName() + " fine esecuzione.");
}
}

class Esa
{
public void fai(String nomefile) throws IOException {
Scanner sc = new Scanner(new BufferedReader(new FileReader(nomefile)));
Giro g = null, primo = null;
try {
int cicli = sc.nextInt();
Giro prev = null;
int id = 1;
for (;;) {
String parola = sc.next();
g = new Giro(cicli, parola);
g.setName("Thread-"+id);
id = id+1;
g.start();
if (prev != null)
prev.setNext(g);
prev = g;
if (primo == null)
primo = g;
}
}
catch (Exception e) {}
finally {
sc.close();
}

if (primo != null) {
g.setNext(primo);
primo.vai();
}
}
}


ti ho colorato le modifiche, così le puoi replicare sul tuo codice.

grazie ! le provo subito . Comunque il realtà il mio sbaglio era scordarmi che si stava parlando di Thread e quindi che l'esecuzione è in parallelo l'una con l'altra . Io ragionavo come se il primo thread una volta in esecuzione il successivo si stoppasse -.-"

Cmq ho provato ad eliminare synchronized e mi da errore . NOn capisco , il perchè .
Mi deve sfuggire qualcosa sull'utilità di utilizzare synchronized in generale .
COme mai è fondamentale in questo esercizio ? ;)

p.s : a lezione siccome lo spiegano cosi in 3 secondi , poi chiaramente sta a me documentarmi sui libri . Ma dovunque cerco , lo ritrovo spiegato con le solite 3 o 4 parole in fila e non riesco a capire la verà utilità del synchronized , potrei impararlo meccanicamente , ma poi che vantaggi ne trarrei ? io direi nessuni :)

Vi ringrazio ancora per l'aiuto che mi date !!!

banryu79
06-09-2010, 10:09
Qui aspetta è synchronized . Se esso non lo fosse , che cambierebbe ? Perchè io so che se è synchronized più thread non possono eseguire la stessa funzione contemporaneamente , però in questo caso non potrebbe anche venir omesso il synchonized ?
E' synchronized perchè nel corpo del metodo 'aspetta' c'è una chiamata a wait(). Se consulti i javadoc del metodo wait() vedrai che è scritto chiaramente che il thread corrente per invocare wait deve possedere l'object monitor (e se così non è viene lanciata una IllegalMonitorException).

La parola chiave syncrhonized è un meccanismo per ottenere appunto il lock intrinseco (object monitor) di un oggetto.

Per farti capire meglio, l'oggetto in questione sarebbe il 'this', cioè l'stanza corrente di Giro. Ogni istanza in Java ha un 'monitor'. Per fare in modo che un thread ottenga il lock sul monitor intrinseco di un oggetto si usa appunto syncrhonized (puoi dichiarare synchronized tutto il metodo, oppure una parte specifica dentro il corpo di un metodo, con il blocco syncrhonized).

Ad esempio questo:

public synchronized void aspetta() {
try {
while (!interrupted())
wait();
} catch(InterruptedException e) {}
}

è perfettamente identico a questo:

public void aspetta() {
synchronized(this) {
try {
while (!interrupted())
wait();
} catch(InterruptedException e) {}
}
}

aeroxr1
06-09-2010, 10:16
E' synchronized perchè nel corpo del metodo 'aspetta' c'è una chiamata a wait(). Se consulti i javadoc del metodo wait() vedrai che è scritto chiaramente che il thread corrente per invocare wait deve possedere l'object monitor (e se così non è viene lanciata una IllegalMonitorException).

La parola chiave syncrhonized è un meccanismo per ottenere appunto il lock intrinseco (object monitor) di un oggetto.

Per farti capire meglio, l'oggetto in questione sarebbe il 'this', cioè l'stanza corrente di Giro. Ogni istanza in Java ha un 'monitor'. Per fare in modo che un thread ottenga il lock sul monitor intrinseco di un oggetto si usa appunto syncrhonized (puoi dichiarare synchronized tutto il metodo, oppure una parte specifica dentro il corpo di un metodo, con il blocco syncrhonized).

Ad esempio questo:

public synchronized void aspetta() {
try {
while (!interrupted())
wait();
} catch(InterruptedException e) {}
}

è perfettamente identico a questo:

public void aspetta() {
synchronized(this) {
try {
while (!interrupted())
wait();
} catch(InterruptedException e) {}
}
}



grazie !!! Te si che spieghi bene :)

Un ultima cosa , non sarebbe mica cambiato niente se al posto della funziona vai() avessi fatto :

primo.interrupt()
next.interrupt()

giusto ?

dico giusto , ma facendo cosi mi da una stampa leggermente diversa :stordita:

p.s : i javadoc sono reperibili al sito che mi avete linkato in precedenza vero ? :)

banryu79
06-09-2010, 10:43
grazie !!! Te si che spieghi bene :)

Un ultima cosa , non sarebbe mica cambiato niente se al posto della funziona vai() avessi fatto :

primo.interrupt()
next.interrupt()

giusto ?

dico giusto , ma facendo cosi mi da una stampa leggermente diversa :stordita:

p.s : i javadoc sono reperibili al sito che mi avete linkato in precedenza vero ? :)
Sì, puoi anche chiamare l'interrupt direttamente.
Il motivo dietro al fatto che "ti da una stampa leggermente diversa" non ha niente a che vedere col fatto di chiamare interrupt() direttamente piuttosto che tramite un metodo wrapper (fa solo quello: cioè chiama interrupt, dunque non aggiunge ne toglie nulla).

Vedrai che se lanci più volte il programma otterai sempre delle leggere variazioni all'ordine di stampa, però la sincronicità tra i thread Giro per come è dichiarata nel codice sarà sempre garantita. (se poi sei veramente incuriosito puoi provare a chiedere lumi al prof, chissà...)

Per ora ti consiglio di non mettere troppa carne al fuoco e di darti del tempo per digerire i nuovi concetti e magari esercitarti un po' per verificare & consolidare le conoscenze acquisite.

Per i link, ecco:
- Java SE 6 Documentation (http://download.oracle.com/javase/6/docs/) (documentazione varia, tra cui i javadoc che puoi anche scaricare).
- The Really Big Index (http://download.oracle.com/javase/tutorial/reallybigindex.html) (compendio dei Java Tutorial, anche questi scaricabili).

aeroxr1
06-09-2010, 12:10
Sì, puoi anche chiamare l'interrupt direttamente.
Il motivo dietro al fatto che "ti da una stampa leggermente diversa" non ha niente a che vedere col fatto di chiamare interrupt() direttamente piuttosto che tramite un metodo wrapper (fa solo quello: cioè chiama interrupt, dunque non aggiunge ne toglie nulla).

Vedrai che se lanci più volte il programma otterai sempre delle leggere variazioni all'ordine di stampa, però la sincronicità tra i thread Giro per come è dichiarata nel codice sarà sempre garantita. (se poi sei veramente incuriosito puoi provare a chiedere lumi al prof, chissà...)

Per ora ti consiglio di non mettere troppa carne al fuoco e di darti del tempo per digerire i nuovi concetti e magari esercitarti un po' per verificare & consolidare le conoscenze acquisite.

Per i link, ecco:
- Java SE 6 Documentation (http://download.oracle.com/javase/6/docs/) (documentazione varia, tra cui i javadoc che puoi anche scaricare).
- The Really Big Index (http://download.oracle.com/javase/tutorial/reallybigindex.html) (compendio dei Java Tutorial, anche questi scaricabili).

si infatti sono qui che sto facendo esercizi per la preparazione dell'esame ;)

Grazie di tutto !!!

banryu79
06-09-2010, 12:18
si infatti sono qui che sto facendo esercizi per la preparazione dell'esame ;)

Grazie di tutto !!!
Prego.

Tanto per toglierti lo sfizio, ammesso che tu ne abbia il tempo, con un'oretta di attenta lettura puoi cominciare a intuire il perchè delle "stranezze" nell'ordine di stampa, leggendo in ordine le voci di questo tutorial:
- Lesson: Concurrency (http://download.oracle.com/javase/tutorial/essential/concurrency/index.html)

E' utile per almeno aver sentito almeno una descrizione introduttiva a certi termini, concetti e alcune problematiche relative alla programmazione concorrente, sia in generale che per gli aspetti legati all'implementazione che questa assume nella tecnologia Java.

In bocca al lupo per l'esame ;)

aeroxr1
06-09-2010, 12:26
Prego.

Tanto per toglierti lo sfizio, ammesso che tu ne abbia il tempo, con un'oretta di attenta lettura puoi cominciare a intuire il perchè delle "stranezze" nell'ordine di stampa, leggendo in ordine le voci di questo tutorial:
- Lesson: Concurrency (http://download.oracle.com/javase/tutorial/essential/concurrency/index.html)

E' utile per almeno aver sentito almeno una descrizione introduttiva a certi termini, concetti e alcune problematiche relative alla programmazione concorrente, sia in generale che per gli aspetti legati all'implementazione che questa assume nella tecnologia Java.

In bocca al lupo per l'esame ;)

Non trovo i link per scaricarli direttamente sul pc senza consultarli online , va bè mal di poco a limite scaricherò tutte le pagine web sul pc :)

Grazie ancora di tutto e crepi !!!

banryu79
06-09-2010, 12:31
Ehm, con il passaggio da Sun a Oracle e relativa riorganizzazione del sito aziendale ci ho messo un po' per capire dove trovare la pagina di accesso alla documentazione per il download: eccola (http://www.oracle.com/technetwork/java/javase/documentation/index.html)

aeroxr1
06-09-2010, 12:45
Ehm, con il passaggio da Sun a Oracle e relativa riorganizzazione del sito aziendale ci ho messo un po' per capire dove trovare la pagina di accesso alla documentazione per il download: eccola (http://www.oracle.com/technetwork/java/javase/documentation/index.html)

si in effetti è un incasinato quel sito li...

Ciao !!!

aeroxr1
06-09-2010, 15:05
volevo chiedere una cosa che riguarda la consultazione della documentazione .

io di solito uso , per vedere la lunghezza di un vettore questo codice :

vettore.length

ho cercato nella classe array , però ho solo trovato il metodo getLenght() . Per vedere oltre che ai metodi di una classe anche i membri dove devo andare a vedere ? :)

E' la prima volta che consulto la documentazione , e mi garbava , perchè mi sembra molto ben fatta :)

banryu79
06-09-2010, 15:46
...
ho cercato nella classe array , però ho solo trovato il metodo getLenght() . Per vedere oltre che ai metodi di una classe anche i membri dove devo andare a vedere ? :)

La documentazione dei javadoc riporta l'interfaccia pubblica delle classi: se prendi ad esempio la classe java.util.ArrayList (che è una implementazione dell'interfaccia java.util.List) vedrai che i metodi riportati nei javadoc sono solo quelli public o protected, non troverai documentati i metodi private.

La stragrande maggioranza dei campi di istanza di una classe tipica, rappresentano lo stato di un'istanza di quella classe e non sono quasi mai public, ma quasi sempre private o protected (incapsulamento).
E' per questo che non li vedi nella documentazione (invece è più comune imbattersi in membri statici pubblici).

Comunque alla documentazione dei javadoc è utile poter affiancare i sorgenti del JDK: in quel caso ti apri il sorgente della classe che ti interessa e puoi leggere tutto.
Normalmente uno non consulta queste risorse aprendole una alla volta; queste informazioni sono di solito consultate tramite l'IDE, cioè l'ambiente di sviluppo con cui si programma (per Java, due su tutti: NetBeans o Eclipse) che incorpora delle funzionalità apposite per visualizzare le informazioni richieste nello stesso ambiente in cui si scrive il codice.
Gli IDE fanno questo e molto altro.

Siamo decisamente OT però...

aeroxr1
06-09-2010, 20:39
La documentazione dei javadoc riporta l'interfaccia pubblica delle classi: se prendi ad esempio la classe java.util.ArrayList (che è una implementazione dell'interfaccia java.util.List) vedrai che i metodi riportati nei javadoc sono solo quelli public o protected, non troverai documentati i metodi private.

La stragrande maggioranza dei campi di istanza di una classe tipica, rappresentano lo stato di un'istanza di quella classe e non sono quasi mai public, ma quasi sempre private o protected (incapsulamento).
E' per questo che non li vedi nella documentazione (invece è più comune imbattersi in membri statici pubblici).

Comunque alla documentazione dei javadoc è utile poter affiancare i sorgenti del JDK: in quel caso ti apri il sorgente della classe che ti interessa e puoi leggere tutto.
Normalmente uno non consulta queste risorse aprendole una alla volta; queste informazioni sono di solito consultate tramite l'IDE, cioè l'ambiente di sviluppo con cui si programma (per Java, due su tutti: NetBeans o Eclipse) che incorpora delle funzionalità apposite per visualizzare le informazioni richieste nello stesso ambiente in cui si scrive il codice.
Gli IDE fanno questo e molto altro.

Siamo decisamente OT però...


il mio prof non ci fa usare NetBeans ma solo il blocco note -.-"

grazie di tutto ! siete miticiiiiiii !!! :)