Torna indietro   Hardware Upgrade Forum > Software > Programmazione

Tascabile e con Android: BOOX Go 6 Gen II è diverso da tutti gli altri e-reader
Tascabile e con Android: BOOX Go 6 Gen II è diverso da tutti gli altri e-reader
BOOX Go 6 Gen II porta per la prima volta il supporto allo stilo su un e-reader da 6 pollici, affiancando 3 GB di RAM al collaudato Snapdragon 665 e un design rivisto con scocca posteriore a costolature. Su carta la proposta è interessante, ma Android 11 fuori supporto, l'assenza di un alloggiamento per il pennino e un'autonomia ridotta rispetto agli e-reader tradizionali sono i compromessi da accettare
Recensione Lenovo Idea Tab Plus: il tablet da 12 pollici che costa meno di 300 euro
Recensione Lenovo Idea Tab Plus: il tablet da 12 pollici che costa meno di 300 euro
Lenovo Idea Tab Plus prova a portare un display da 12,1 pollici 2.5K, quattro speaker Dolby Atmos e una batteria da 10.200 mAh sotto la soglia psicologica dei 300 euro, penna inclusa. Lo abbiamo usato per oltre una settimana per capire dove l'azienda ha tagliato e dove invece ha tenuto il punto
Oltre il contante e le crypto: tutto sull'Euro Digitale e la nuova sovranità monetaria europea
Oltre il contante e le crypto: tutto sull'Euro Digitale e la nuova sovranità monetaria europea
L'euro digitale è una valuta fiat che entrerà in vigore nei prossimi anni. L'obiettivo principale è quello di ridurre la dipendenza dalle piattaforme di pagamento digitali statunitensi e offrire ai cittadini un modo semplice per trasferire denaro. Anche offline, anche in maniera (pseudo)anonima
Tutti gli articoli Tutte le news

Vai al Forum
Rispondi
 
Strumenti
Old 12-10-2009, 15:48   #1
CertainDeath
Member
 
L'Avatar di CertainDeath
 
Iscritto dal: Sep 2008
Città: Padova
Messaggi: 172
[Java] Gestione Threads

Salve ragazzi, devo realizzare un programma in Java che mediante la gestione dei threads incrementa e decrementa una variabile.
Mi son costruito 4 classi.. sono alle prime armi e nonostante il problema sia semplice per me non è immediatissimo.

Il main:

Codice:
public class main {
	public static void main(String[] args) {
		Thread thread = new Thread();
		Incrementa incrementa = new Incrementa(thread);
		Decrementa decrementa = new Decrementa(thread);
		Thread aggiungo = new Thread(incrementa);
		Thread sottraggo = new Thread(decrementa);
		aggiungo.start();
		sottraggo.start();

		try {
			Thread.sleep(5000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		System.out.println();
	}

}

Codice:
public class Thread {
	int numeri = 0;

	public void plus() {
		numeri++;
	}

	public void minus() {
		numeri--;
	}
}

Codice:
public class Incrementa implements Runnable {
	Thread th;

	public Incrementa(Thread th) {
		this.th = th;
	}

	public void run() {

		th.plus();
	}

}

Codice:
public class Decrementa implements Runnable {
	Thread th;

	public Decrementa(Thread th) {
		this.th = th;
	}

	public void run() {

		th.minus();
	}

}
Ringrazio tutti coloro i quali aiuteranno un nabbo come me
__________________
PACKARD BELL Easy Note TJ75@CPU INTEL Core i5 430M //GPU ATI RADEON HD 5470//RAM CORSAIR 4GB DDR3// HD WESTERN DIGITAL 640GB SATAII 3.0 GB/s
CertainDeath è offline   Rispondi citando il messaggio o parte di esso
Old 12-10-2009, 16:43   #2
PGI-Bis
Senior Member
 
L'Avatar di PGI-Bis
 
Iscritto dal: Nov 2004
Città: Tra Verona e Mantova
Messaggi: 4553
Cambia il nome della tua classe Thread in Contatore.

Aggiungi il modificatore volatile al campo numeri di Contatore:

private volatile int numeri = 0;

Dopodichè il programma aumenta e diminuisce di uno il valore di contatore e termina.

Codice:
public class Main {

	public static void main(String[] args) {
		Contatore contatore = new Contatore();
		Incrementa incrementa = new Incrementa(contatore);
		Decrementa decrementa = new Decrementa(contatore);
		Thread aggiungo = new Thread(incrementa);
		Thread sottraggo = new Thread(decrementa);
		aggiungo.start();
		sottraggo.start();
		try {
			Thread.sleep(1000);
		} catch(InterruptedException ex) {
			ex.printStackTrace();
			return;
		}
		System.out.println("Contatore vale: " + contatore.numeri);
	}
}

class Contatore {
	volatile int numeri = 0;
	
	public void plus() {
		numeri++;
	}	
	
	public void minus() {
		numeri--;
	}
}

class Incrementa implements Runnable {

	Contatore th;
	
	Incrementa(Contatore th) {
		this.th = th;	
	}
	
	public void run() {
		th.plus();
	}
}

class Decrementa implements Runnable {

	Contatore th;
	
	Decrementa(Contatore th) {
		this.th = th;
	}
	
	public void run() {
		th.minus();
	}	
}
__________________
Uilliam Scecspir ti fa un baffo? Gioffri Cioser era uno straccione? E allora blogga anche tu, in inglese come me!
PGI-Bis è offline   Rispondi citando il messaggio o parte di esso
Old 12-10-2009, 18:57   #3
CertainDeath
Member
 
L'Avatar di CertainDeath
 
Iscritto dal: Sep 2008
Città: Padova
Messaggi: 172
Cosa sta a significare "Volatile" non l'ho mai sentita come istruzione.. Grazie della precisa risposta

La cosa strana che rimane come valore sempre 0.. perchè? non incrementa la variabile?
__________________
PACKARD BELL Easy Note TJ75@CPU INTEL Core i5 430M //GPU ATI RADEON HD 5470//RAM CORSAIR 4GB DDR3// HD WESTERN DIGITAL 640GB SATAII 3.0 GB/s

Ultima modifica di CertainDeath : 12-10-2009 alle 19:12.
CertainDeath è offline   Rispondi citando il messaggio o parte di esso
Old 12-10-2009, 21:50   #4
PGI-Bis
Senior Member
 
L'Avatar di PGI-Bis
 
Iscritto dal: Nov 2004
Città: Tra Verona e Mantova
Messaggi: 4553
volatile serve per obbligare i thread a leggere il valore di un campo dalla memoria condivisa e per obbligare gli stessi thread ad aggiornare quella memoria quando cambiano il valore di quel campo.

Senza volatile, e non usando altri meccanismi di sincronizzazione, quando un thread "legge" un campo è libero di non tener conto del valore che quel campo ha e, quando "scrive su" un campo, è libero di non aggiornare la regione di memoria condivisa corrispondente a quel campo.
__________________
Uilliam Scecspir ti fa un baffo? Gioffri Cioser era uno straccione? E allora blogga anche tu, in inglese come me!
PGI-Bis è offline   Rispondi citando il messaggio o parte di esso
Old 12-10-2009, 21:54   #5
PGI-Bis
Senior Member
 
L'Avatar di PGI-Bis
 
Iscritto dal: Nov 2004
Città: Tra Verona e Mantova
Messaggi: 4553
Quote:
Originariamente inviato da CertainDeath Guarda i messaggi
La cosa strana che rimane come valore sempre 0.. perchè? non incrementa la variabile?
Il valore iniziale del campo è zero. Il Thread incrementa aumenta quel valore di uno, il Thread decrementa lo riduce di uno, il valore che risulta non può che essere zero.

Nota che i due Thread non eseguono dei cicli di incremento o decremento: uno fa un +1 e schiatta subito dopo, l'altro fa un -1 e si defila altrettando rapidamente. E' come se ci fosse scritto:

Codice:
int valore = 0;
valore++
valore--;
System.out.println(valore);
__________________
Uilliam Scecspir ti fa un baffo? Gioffri Cioser era uno straccione? E allora blogga anche tu, in inglese come me!
PGI-Bis è offline   Rispondi citando il messaggio o parte di esso
Old 12-10-2009, 22:10   #6
CertainDeath
Member
 
L'Avatar di CertainDeath
 
Iscritto dal: Sep 2008
Città: Padova
Messaggi: 172
Per fare dei cicli di incremento e decremento posso usare Synchronized? oppure devo usare i cicli if.. ecc?
__________________
PACKARD BELL Easy Note TJ75@CPU INTEL Core i5 430M //GPU ATI RADEON HD 5470//RAM CORSAIR 4GB DDR3// HD WESTERN DIGITAL 640GB SATAII 3.0 GB/s
CertainDeath è offline   Rispondi citando il messaggio o parte di esso
Old 12-10-2009, 22:40   #7
PGI-Bis
Senior Member
 
L'Avatar di PGI-Bis
 
Iscritto dal: Nov 2004
Città: Tra Verona e Mantova
Messaggi: 4553
I cicli li fai coi cicli .

synchronized, volatile, pipicchio e pipacchio ti interessano solo nel momento in cui riscontri che il tuo Thread sta cercando di accedere ad un valore che non è stato lui a creare.

Tutto il resto è immutato, i for sono for, gli if sono if, gli interi sono interi eccetera.
__________________
Uilliam Scecspir ti fa un baffo? Gioffri Cioser era uno straccione? E allora blogga anche tu, in inglese come me!
PGI-Bis è offline   Rispondi citando il messaggio o parte di esso
Old 13-10-2009, 00:19   #8
nuovoUtente86
Senior Member
 
Iscritto dal: Mar 2007
Messaggi: 7863
Secondo le specifiche però, in questo caso, volatile non dovrebbe garantire l' atomicità in quanto il valore della variabile dipende dal precedente (trattandosi di un contatore).
nuovoUtente86 è offline   Rispondi citando il messaggio o parte di esso
Old 13-10-2009, 01:05   #9
PGI-Bis
Senior Member
 
L'Avatar di PGI-Bis
 
Iscritto dal: Nov 2004
Città: Tra Verona e Mantova
Messaggi: 4553
L'unica atomicità garantita da volatile è sulle letture o scritture dei valori a 64bit. Per il resto tutte le letture e scritture sono atomiche di loro.

Che quello sia un contatore è tutto da verificare: ho messo il nome che m'è venuto ma in origine era un Thread.
__________________
Uilliam Scecspir ti fa un baffo? Gioffri Cioser era uno straccione? E allora blogga anche tu, in inglese come me!
PGI-Bis è offline   Rispondi citando il messaggio o parte di esso
Old 13-10-2009, 01:40   #10
nuovoUtente86
Senior Member
 
Iscritto dal: Mar 2007
Messaggi: 7863
Ho ripreso il termine contatore giusto perchè lo avevi già utilizzato: potrebbe rappresentare un' istantanea degli utenti su una coda o qualsiasi altra cosa ma non è questa la cosa importante.
Sicuramente read e write (tranne che per long e double)sono garantiti dalla jvm, ma numeri++(numeri=numeri+1) e numeri-- non sono eseguite in maniera indivisibile (come invece garantisce qualche compilatore c++).
In questo caso il risultato risulta corretto forse più per la sincronizzazione sull' ultima istruzione del thread che lancia (ma non ne sono affatto sicuro) che per l' utilizzo di volatile. Se mettissimo i cicli e lanciassimo più di 2 thread il risultato non credo sarebbe coerente.

Ultima modifica di nuovoUtente86 : 13-10-2009 alle 01:49.
nuovoUtente86 è offline   Rispondi citando il messaggio o parte di esso
Old 13-10-2009, 12:59   #11
PGI-Bis
Senior Member
 
L'Avatar di PGI-Bis
 
Iscritto dal: Nov 2004
Città: Tra Verona e Mantova
Messaggi: 4553
Come dicono i francesi, calma e gesso .

A me volatile interessa perchè senza quel "System.out.println(contatore.numeri)" può non riflettere le mutazioni che i due altri thread producono su "numeri".

Dopodichè, assumendo che i due thread aggiungo e sottraggo terminino la loro esecuzione in quel secondo di attesa del main, stamperà o zero o uno o meno uno.
__________________
Uilliam Scecspir ti fa un baffo? Gioffri Cioser era uno straccione? E allora blogga anche tu, in inglese come me!
PGI-Bis è offline   Rispondi citando il messaggio o parte di esso
Old 13-10-2009, 13:53   #12
nuovoUtente86
Senior Member
 
Iscritto dal: Mar 2007
Messaggi: 7863
Su questo non ci piove, ma presumo che intrinsecamento lo scopo dell' esercizio fosse anche attuare una politica di sincronizzazione, che molto grezzamente (forzando alla fine la sequenzialità) poteva essere garantita imponendo una join(), ma meglio con l' utilizzo di AtomicInteger.
A proposito del package Atomic volevo chiederti se lo stesso garantisce l' atomicità anche su architetture multicore ovvero se un eventuale thread che esegue su un altro core venga sospeso se tenta l' accesso ad una variabile impegnata in una operazione atomica non ancora conclusa?
nuovoUtente86 è offline   Rispondi citando il messaggio o parte di esso
Old 13-10-2009, 14:16   #13
PGI-Bis
Senior Member
 
L'Avatar di PGI-Bis
 
Iscritto dal: Nov 2004
Città: Tra Verona e Mantova
Messaggi: 4553
Sì, gli AtomicXYZ definiscono anche operazioni atomiche nel senso che i vari getAndSet, setAndGet, addAndSet eccetera sono unitarie.

A meno di bug - e nella bugparade qualcuno ce n'era - l'architettura è sempre irrilevante. Se noti tutto ciò che si trova nel package concurrent spiega i propri effetti in relazione alle norme del java memory model e il JMM dice che se una cosa si chiama "Java" allora deve fare una certa cosa, a prescindere dal sistema ospite.

Come si faccia concretamente è esemplificato in

http://gee.cs.oswego.edu/dl/jmm/cookbook.html
__________________
Uilliam Scecspir ti fa un baffo? Gioffri Cioser era uno straccione? E allora blogga anche tu, in inglese come me!
PGI-Bis è offline   Rispondi citando il messaggio o parte di esso
Old 13-10-2009, 14:45   #14
nuovoUtente86
Senior Member
 
Iscritto dal: Mar 2007
Messaggi: 7863
si effettivamente far dipendere il comportamento dalla piattaforma avrebbe negato l' essenza stessa di JAva.
Ragionando un po sui thread, mi è sorto un dubbio ovvero se nella work area privata di ogni thread, in caso di oggetti che ne puntano altri, questi vengano mantenuti i riferimenti (quindi mantenuti in shared) oppure si clonano effettivamente nella zona privata tutti gli oggetti presenti sulla catena di reference
nuovoUtente86 è offline   Rispondi citando il messaggio o parte di esso
Old 13-10-2009, 15:06   #15
PGI-Bis
Senior Member
 
L'Avatar di PGI-Bis
 
Iscritto dal: Nov 2004
Città: Tra Verona e Mantova
Messaggi: 4553
La metafora della copia vale solo per il valore delle variabili condivise che, per un reference, sarebbe il valore del puntatore. Eventuali riferimenti indiretti collegati a quel puntatore sono a loro volta soggetti alle norme del modello di memoria. E' il tipico caso della variabile locale. Se ho un thread che dichiara e inizializza localmente un punto:

Codice:
new Thread() {
    public void run() {
        Point p = new Point(10, 20);
        altroThread.valuta(p);
    }
}.start();
Il modello di memoria dice che essendo "p" locale il secondo thread che riceve p attraverso valuta non vedrà mai p valere null ma sempre p che vale un certo punto.

Il problema è che se p è locale NON sono locali i campi x e y accessibili tramite p e dunque il loro valore sarà o non sarà 10 e 20 a seconda che per x e y si possano dire rispettate le norme sulla sincronizzazione delle letture con le scritture - nel caso specifico di Point non lo sono e l'unica garanzia che si ha è che p sia "properly constructed", cioè x e y varranno certamente almeno zero.

E' lì che entra in gioco la famosa relazione "happens-before" che va sempre valutata sia nel rapporto intre-thread che nel rapporto intra-thread. Ad esempio se in un Thread A avessimo:

Codice:
Point p = new Point();
p.y = 300;
synchronized(p) {
   p.x = 10;
}
threadB.valuta(p);

...ThreadB.valuta
synchronized(p) {
    int x = p.x;
    int y = p.y
}
ThreadB vedrebbe sia x valere 10 sia y valere 300. Vede x = 10 perchè l'entrata di ThreadB nel blocco sincronizzato su p obbliga la lettura dell'ultimo valore scritto in un blocco sincronizzato su p. Vede y = 300 perchè nel Thread A tra y = 300 e x = 10 c'è una relazione happens-before e questa relazione è sempre transitiva.
__________________
Uilliam Scecspir ti fa un baffo? Gioffri Cioser era uno straccione? E allora blogga anche tu, in inglese come me!
PGI-Bis è offline   Rispondi citando il messaggio o parte di esso
Old 13-10-2009, 19:11   #16
nuovoUtente86
Senior Member
 
Iscritto dal: Mar 2007
Messaggi: 7863
Quindi se abbiamo un array di int su cui operano diversi thread, la "copia" locale ad ogni thread riguarda il reference all' oggetto piuttosto che il vettore stesso.
L' esempio non è casuale, perchè ricordo una vecchia discussione, su un altro forum, in cui si parlava proprio di assegnamenti del tipo
v[posizione]=10;
non scaricati sulla memoria dell' applicazione, eppure mantenendo copia solo del reference non dovrebbe sussistere il problema.
nuovoUtente86 è offline   Rispondi citando il messaggio o parte di esso
Old 13-10-2009, 19:28   #17
PGI-Bis
Senior Member
 
L'Avatar di PGI-Bis
 
Iscritto dal: Nov 2004
Città: Tra Verona e Mantova
Messaggi: 4553
E' tutto locale, nel senso che se ho un riferimento ad un array

x

senza sincronismi ogni thread ha il suo riferimento x. Quando il thread agisce sul componente [0] agisce su una copia locale del componente di un array locale.

Se garantiamo la condivisione del riferimento all'array x allora ogni volta che il thread va a leggere x legge l'ultimo valore che questo x ha (cioè se qualcuno redirige il riferimento verso un altro array allora il thread agirà su quell'array). Questo però non si estende ai componenti di quell'array:

x[1] sarà un valore locale che il thread non è tenuto ad inizializzare con lo stesso valore che ha l'array a cui x punta.

Esempio.

final int[] array = new int[20];

final ci dice che chiunque legga array lo vedrà come array di 20 componenti ognuno dei quali vale zero.

1) thread 1: array[0] = 20;
2) thread 2: System.out.println(array[0]);

thread 2 può stampare zero perchè quando thread 1 scrive sul componente 0 di array non è tenuto a far sì che tale scrittura sia visibile ai thread che leggerano quel valore.

E questo nonostante sia thread 1 che thread 2 vedano "array" puntare alla stessa regione di memoria.
__________________
Uilliam Scecspir ti fa un baffo? Gioffri Cioser era uno straccione? E allora blogga anche tu, in inglese come me!
PGI-Bis è offline   Rispondi citando il messaggio o parte di esso
Old 13-10-2009, 19:39   #18
PGI-Bis
Senior Member
 
L'Avatar di PGI-Bis
 
Iscritto dal: Nov 2004
Città: Tra Verona e Mantova
Messaggi: 4553
Qui c'è una serie molto carina di Sun sulla programmazione parallela

http://channelsun.sun.com/video/an+i...g+/25947206001

la segnalo perchè c'è un punto in cui si "vede" questa faccenda della località dei riferimenti detenuti dai thread nelle architetture multicore dove lungo la strada che dal programma nella memoria principale arriva al singolo core a un certo punto la memoria cessa di essere condivisa e "ognuno fa da sè".
__________________
Uilliam Scecspir ti fa un baffo? Gioffri Cioser era uno straccione? E allora blogga anche tu, in inglese come me!
PGI-Bis è offline   Rispondi citando il messaggio o parte di esso
Old 13-10-2009, 20:21   #19
nuovoUtente86
Senior Member
 
Iscritto dal: Mar 2007
Messaggi: 7863
E se usassimo un' ArrayList di Integer in luogo dell' array avremmo lo stesso comportamento?
nuovoUtente86 è offline   Rispondi citando il messaggio o parte di esso
Old 13-10-2009, 21:03   #20
PGI-Bis
Senior Member
 
L'Avatar di PGI-Bis
 
Iscritto dal: Nov 2004
Città: Tra Verona e Mantova
Messaggi: 4553
Sì, vale in generale per ogni cosa che si trovi nella memoria condivisa.
__________________
Uilliam Scecspir ti fa un baffo? Gioffri Cioser era uno straccione? E allora blogga anche tu, in inglese come me!
PGI-Bis è offline   Rispondi citando il messaggio o parte di esso
 Rispondi


Tascabile e con Android: BOOX Go 6 Gen II è diverso da tutti gli altri e-reader Tascabile e con Android: BOOX Go 6 Gen II &egrav...
Recensione Lenovo Idea Tab Plus: il tablet da 12 pollici che costa meno di 300 euro Recensione Lenovo Idea Tab Plus: il tablet da 12...
Oltre il contante e le crypto: tutto sull'Euro Digitale e la nuova sovranità monetaria europea Oltre il contante e le crypto: tutto sull'Euro D...
Recensione HONOR Magic V6: spessore record e super batteria. È lui il fold da battere? Recensione HONOR Magic V6: spessore record e sup...
Redmi Pad 2 9.7: ampio display, economico e peso contenuto, ma qualche limite nelle prestazioni Redmi Pad 2 9.7: ampio display, economico e peso...
Piccolo è bello: Cisco presenta A...
Z.AI avvia un data center da 1 gigawatt....
Microsoft e Mistral annunciano un accord...
Grazie al Very Large Telescope potrebbe ...
Sony FX5: RAW interno X-OCN e Open Gate ...
AMD e Anthropic, affare fatto: 5 miliard...
Cyber Arena Tour 2026, WINDTRE BUSINESS ...
Wistron ha aperto il primo stabilimento ...
"Così è facile perder...
Peak Design ripensa la staffa a L: il tr...
Samsung: ufficiale la serie Galaxy Z Fol...
Galaxy Watch Ultra2 e Watch9 ufficiali: ...
Un razzo spaziale Falcon 9 ha lanciato l...
Microlino: dal rischio di fallimento all...
SpaceX, uno stadio di Falcon 9 si schian...
Chromium
GPU-Z
OCCT
LibreOffice Portable
Opera One Portable
Opera One 106
CCleaner Portable
CCleaner Standard
Cpu-Z
Driver NVIDIA GeForce 546.65 WHQL
SmartFTP
Trillian
Google Chrome Portable
Google Chrome 120
VirtualBox
Tutti gli articoli Tutte le news Tutti i download

Strumenti

Regole
Non Puoi aprire nuove discussioni
Non Puoi rispondere ai messaggi
Non Puoi allegare file
Non Puoi modificare i tuoi messaggi

Il codice vB è On
Le Faccine sono On
Il codice [IMG] è On
Il codice HTML è Off
Vai al Forum


Tutti gli orari sono GMT +1. Ora sono le: 23:37.


Powered by vBulletin® Version 3.6.4
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd.
Served by www3v