Torna indietro   Hardware Upgrade Forum > Software > Programmazione

 Recensione OPPO Find X10 Pro Max: un top di gamma completo con tre fotocamere da 200MP
Recensione OPPO Find X10 Pro Max: un top di gamma completo con tre fotocamere da 200MP
OPPO ha appena lanciato sul mercato la nuova serie Find X10, che ha come smartphone premium il Find X10 Pro Max, uno smartphone completo, che fa del comparto fotografico il suo vero punto di forza. Ma sono tante le novità, tra cui l'AI che adesso diventa agentica. Ma andiamo a vedere nel dettaglio questo nuovo smartphone.
WoW Forever provato: il MMORPG che la community chiedeva da anni è arrivato
WoW Forever provato: il MMORPG che la community chiedeva da anni è arrivato
Abbiamo provato la beta di World of Warcraft: Forever, il Classic+ di Blizzard in arrivo il 4 novembre: la nuova razza Skyborne restituisce la sensazione di un gioco nuovo, ma le zone storiche conservano la noia divertita di Classic. Classi ribilanciate, sciamani anche nell'Alleanza e un motore grafico che in 4K gira bene anche su una RTX 3070. Cosa cambia in Forever? La risposta nell'articolo
TCL P80 Ultra: con un display AMOLED opaco è una gioia per gli occhi e per le dita
TCL P80 Ultra: con un display AMOLED opaco è una gioia per gli occhi e per le dita
TCL P80 Ultra abbina per la prima volta un pannello AMOLED alla tecnologia NXTPAPER con finitura opaca, affiancandoci una fotocamera periscopica da 50 MP con zoom ottico 3x, il SoC Dimensity 7400 Elite e una batteria da 5.800 mAh. Nella prova sul campo emergono luminosità di picco molto elevata, comparto fotografico solido per la fascia di prezzo e autonomia nella media, a fronte di velocità di scrittura dello storage piuttosto contenute
Tutti gli articoli Tutte le news

Vai al Forum
Rispondi
 
Strumenti
Old 26-09-2011, 09:05   #1
GByTe87
Senior Member
 
L'Avatar di GByTe87
 
Iscritto dal: Mar 2007
Città: Milano Beach
Messaggi: 1696
[JAVA] Polling su file con thread

Buongiorno a tutti.

Stavo giocando con i thread in java per realizzare un semplice poller che ad intervalli regolari va a verificare se un certo file è presente e, in caso affermativo, lo processa (un banalissimo producer-consumer).

Il tutto funziona, ma ho un solo problema... temo che una volta processato il file il thread consumer rimanga in esecuzione (per dire, nella vista Debug di Eclipse non mi appare [Terminated]).. ho iniziato da poco a giocherellare con i thread e non escludo grosse cazzate.

Per il producer ho usato uno ScheduledExecutorService in modo da poter eseguire il check ogni n secondi.

Ecco il codice:

TestClass.java

Codice:
import java.io.BufferedInputStream;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;

public class TestClass {

	boolean isFilePresent = false;
	String filename;
	File xmlToRead = null;

	public TestClass(String filename) {
		this.filename = filename;
	}

	synchronized void checkFilePresence() {
		System.out.println("[checkFilePresence] IN");

		if (isFilePresent) {
			System.out.println("[checkFilePresence] File già letto.");
			return;
		}

		xmlToRead = new File(filename);

		if (xmlToRead.exists() == false) {
			System.out.println("[checkFilePresence] File non ancora presente..");
			return;
		}

		notify();
		System.out.println("[checkFilePresence] File trovato!");
	}

	synchronized void printFileContent(Producer producer) {
		System.err.println("[printFileContent] IN");

		if (!isFilePresent)
			try {
				wait();
			} catch (InterruptedException exc) {
				System.out.println("Caught InterruptedException in printFileContent");
			}

		// Processo file

		isFilePresent = false;
		producer.stop();

		System.err.println("[printFileContent] Out");
	}
}

Producer.java

Codice:
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;

public class Producer {
	private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
	private ScheduledFuture<?> checkerHandle = null;

	public Producer(final TestClass test) {

		final Runnable checker = new Runnable() {

			@Override
			public void run() {
				test.checkFilePresence();
			}
		};

		checkerHandle = scheduler.scheduleAtFixedRate(checker, 1, 2, TimeUnit.SECONDS);
		scheduler.schedule(new Runnable() {

			@Override
			public void run() {
				checkerHandle.cancel(true);
			}
		}, 60, TimeUnit.SECONDS);
	}

	public void stop() {
		checkerHandle.cancel(true);
	}
}
Consumer.java

Codice:
public class Consumer implements Runnable {

	private TestClass test;
	private Producer producer;

	public Consumer(TestClass test, Producer producer) {
		this.test = test;
		this.producer = producer;
		Thread thread = new Thread(this, "Consumer");
		thread.start();
	}

	public void run() {
		test.printFileContent(producer);

	}
}
Main.java
Codice:
public class Main {

	public static void main(String[] args) {
		
		TestClass test = new TestClass("/home/gibbo/bla.log");
		Producer producer = new Producer(test);
		new Consumer(test, producer);
	}
}
Vi ringrazio
__________________
~ Cthulhu: MacBookPro 13.3" ~ Azathoth: D510MO
GByTe87 è offline   Rispondi citando il messaggio o parte di esso
Old 26-09-2011, 10:15   #2
banryu79
Senior Member
 
L'Avatar di banryu79
 
Iscritto dal: Oct 2007
Città: Padova
Messaggi: 4131
Analizzando il codice che hai postato e il sintomo che rilevi (consumer non "muore") ipotizzo che si verifichi un deadlock.
In particolare quando consumer ottiene il lock sull'istanza di TestClass e isFilePresent vale false: consumer va in wait() durante la chiamata a printFileContent e non rilascia il lock sull'istanza.
Quindi il producer schedulato rimarrà in attesa di poter acquisire il lock chiamando il metodo checkFilePresence sull'istanza di TestClass, lock che non verrà liberato perchè posseduto da consumer che a sua volta attende che producer lo risvegli dalla wait().
__________________

As long as you are basically literate in programming, you should be able to express any logical relationship you understand.
If you don’t understand a logical relationship, you can use the attempt to program it as a means to learn about it.
(Chris Crawford)
banryu79 è offline   Rispondi citando il messaggio o parte di esso
Old 26-09-2011, 10:36   #3
starfred
Senior Member
 
Iscritto dal: Jul 2011
Messaggi: 381
Ho dato un'occhiata un po' rapida e mi sembra di notare che c'è la possibilità che il main termini prima dei thread. Non vedo da nessuna parte un join(). Comunque è un codice molto molto molto contorto, non so se per scelta tua o per specifiche.
Generalmente un thread viene implementato in una classe
esempio:

public class Producer extends Thread {
producer(){...}
run(){...}
}

Gli oggetti che devono essere usati concorrentemente non dovrebbero modificare i thread direttamente, ma dovrebbero essere i thread a modificarsi in base all'oggetto.
Tra l'altro mi sembra di capire il consumatore utilizzi la checkerHandle.cancel(true); per far terminare il loop del produttore; come prima facendo così aumenti di molto la probabilità di starvation.
Comunque non sto dicendo che sia sbagliato, solo che secondo me aumenti di molto la complessità e rischi di commettere parecchi errori.

ciao
__________________
Concluso positivamente con: Kamzata, Ducati82, Arus, TheLastRemnant, ghost driver, alexbull1, DanieleRC5, XatiX

Ultima modifica di starfred : 26-09-2011 alle 10:39.
starfred è offline   Rispondi citando il messaggio o parte di esso
Old 26-09-2011, 11:09   #4
GByTe87
Senior Member
 
L'Avatar di GByTe87
 
Iscritto dal: Mar 2007
Città: Milano Beach
Messaggi: 1696
Quote:
Originariamente inviato da banryu79 Guarda i messaggi
Analizzando il codice che hai postato e il sintomo che rilevi (consumer non "muore") ipotizzo che si verifichi un deadlock.
In particolare quando consumer ottiene il lock sull'istanza di TestClass e isFilePresent vale false: consumer va in wait() durante la chiamata a printFileContent e non rilascia il lock sull'istanza.
Quindi il producer schedulato rimarrà in attesa di poter acquisire il lock chiamando il metodo checkFilePresence sull'istanza di TestClass, lock che non verrà liberato perchè posseduto da consumer che a sua volta attende che producer lo risvegli dalla wait().
Mmm, non capisco come il producer possa rimanere in attesa del consumer, non essendoci alcuna wait() in checkFilePresence.
(Può essere che non abbia afferrato chiaramente il funzionamento di wait() e notify(). Vado a ripassarli per sicurezza. )

Quote:
Originariamente inviato da starfred Guarda i messaggi
Ho dato un'occhiata un po' rapida e mi sembra di notare che c'è la possibilità che il main termini prima dei thread. Non vedo da nessuna parte un join().
Mmm, diciamo che il Main l'ho scritto in fretta giusto per testare le altre classi.

Quote:
Originariamente inviato da starfred Guarda i messaggi
Comunque è un codice molto molto molto contorto, non so se per scelta tua o per specifiche.
Scelta mia, volevo solo provare il pattern Producer-Consumer.

Quote:
Originariamente inviato da starfred Guarda i messaggi
Gli oggetti che devono essere usati concorrentemente non dovrebbero modificare i thread direttamente, ma dovrebbero essere i thread a modificarsi in base all'oggetto.
Tra l'altro mi sembra di capire il consumatore utilizzi la checkerHandle.cancel(true); per far terminare il loop del produttore; come prima facendo così aumenti di molto la probabilità di starvation.
Nell'idea originaria il tutto doveva attendere un singolo file, elaborarlo e poi uscire, quindi fermano il thread producer in quanto "non più necessario".

Quote:
Originariamente inviato da starfred Guarda i messaggi
Comunque non sto dicendo che sia sbagliato, solo che secondo me aumenti di molto la complessità e rischi di commettere parecchi errori.
Posso chiederti se hai voglia di darmi un'indicazione (a parole, pseudocodice o codice) di come avresti strutturato una cosa del genere?

Quote:
Originariamente inviato da starfred Guarda i messaggi
ciao
Ciao e grazie mille ad entrambi!
__________________
~ Cthulhu: MacBookPro 13.3" ~ Azathoth: D510MO
GByTe87 è offline   Rispondi citando il messaggio o parte di esso
Old 26-09-2011, 11:35   #5
banryu79
Senior Member
 
L'Avatar di banryu79
 
Iscritto dal: Oct 2007
Città: Padova
Messaggi: 4131
Quote:
Originariamente inviato da GByTe87 Guarda i messaggi
Mmm, non capisco come il producer possa rimanere in attesa del consumer, non essendoci alcuna wait() in checkFilePresence.
(Può essere che non abbia afferrato chiaramente il funzionamento di wait() e notify(). Vado a ripassarli per sicurezza. )
un thread che invochi un metodo synchronized di una istanza (la tua TestClass) deve acquisire il lock del monitor di quell'istanza prima di poter eseguire il metodo.
Una volta che il thread ha acquisito il lock del monitor dell'istanza, procede a eseguire il corpo del metodo. Quando il thread "esce" dal metodo, rilascia il lock.

Producer (il thread dello scheduled executor) e consumer (il thread che istanzia nel suo construttore) operano entrambi sulla stessa istanza di TestClass, la quale ha i metodi syncrhonized.

Ora immagina che succeda questo:
Codice:
- consumer invoca printFileContent()
- consumer acquisisce il lock dell'istanza di TestClass
- consumer va in wait perchè isFilePresent vale false
- producer invoca checkFilePresence()
- producer non riesce ad aquisire il lock dell'istanza di TestClass, perchè posseduto da consumer
Risultato: consumer è in wait, l'unico thread che lo potrebbe risvegliare è producer, il quale è in attesa di poter acquisire il lock posseduto da consumer... deadlock.
__________________

As long as you are basically literate in programming, you should be able to express any logical relationship you understand.
If you don’t understand a logical relationship, you can use the attempt to program it as a means to learn about it.
(Chris Crawford)

Ultima modifica di banryu79 : 26-09-2011 alle 11:37.
banryu79 è offline   Rispondi citando il messaggio o parte di esso
Old 26-09-2011, 11:40   #6
banryu79
Senior Member
 
L'Avatar di banryu79
 
Iscritto dal: Oct 2007
Città: Padova
Messaggi: 4131
Quote:
Originariamente inviato da starfred Guarda i messaggi
Ho dato un'occhiata un po' rapida e mi sembra di notare che c'è la possibilità che il main termini prima dei thread. Non vedo da nessuna parte un join().
Questo dovrebbe essere ininfluente.
La java virtual machine non "muore" finchè ci sono thread di tipo non-demone in esecuzione.
__________________

As long as you are basically literate in programming, you should be able to express any logical relationship you understand.
If you don’t understand a logical relationship, you can use the attempt to program it as a means to learn about it.
(Chris Crawford)
banryu79 è offline   Rispondi citando il messaggio o parte di esso
Old 26-09-2011, 11:41   #7
GByTe87
Senior Member
 
L'Avatar di GByTe87
 
Iscritto dal: Mar 2007
Città: Milano Beach
Messaggi: 1696
Ok sono un pirla, nell'analizzare la tua risposta non avevo considerato il fatto che i metodi sono dichiarati synchronized.

Capito ora, grazie mille.
__________________
~ Cthulhu: MacBookPro 13.3" ~ Azathoth: D510MO

Ultima modifica di GByTe87 : 26-09-2011 alle 11:45.
GByTe87 è offline   Rispondi citando il messaggio o parte di esso
Old 26-09-2011, 12:26   #8
starfred
Senior Member
 
Iscritto dal: Jul 2011
Messaggi: 381
Ciao, a grandi linee io avrei fatto
Pseudo-codice


Codice:
public class Producer extends Thread {
     producer(string nomefile){ }
     run(){
        TestClass.controllo(nomefile);
     }
}

public class Consumatore extends Thread {
     Consumatore (){...}
     run(){
          TestClass.leggi();
     }
}

public class TestClass {
     boolean pronto=false;
     string file_da_leggere;
     TestClass (){...}

     synchronized void controllo(string nomefile){
      file_da_leggere=nomefile; //Setto il nome del file da leggere
      pronto=true; // Memorizzo che è pronto un dato nuovo
      notify(); //Risveglio un eventuale consumatore in attesa          
      wait(); //Attendo che il consumatore abbia prelevato il dato.
     }


     synchronized void leggi(){
     
      if (!pronto) wait(); //Se non è pronto il file da leggere attendi
      /*Leggi il file_da_leggere */     
      pronto=false; //Resetto nel caso volessi riutilizzare la TestClass
      notify(); //Risveglio il produttore
     }
}

public class Main {

	public static void main(String[] args) {
		
		TestClass test = new TestClass();
		Producer producer = new Producer(test,"/home/gibbo/bla.log");
		Consumatore consumat = new Consumatore (test);
                producer.join();
                consumat.join();

	}
}
Che è la struttura classica di produttore-consumatore. In questa soluzione ho preferito che sia il produttore a fornire l'indirizzo del file da leggere. Attenzione, questo è solo nel caso io abbia un solo produttore ed un solo consumatore ed è bloccante per il produttore (cioè il produttore attende che il dato venga prelevato). Ovviamente si può fare anche una soluzione non bloccante per il produttore e si possono implementare soluzioni con più produttori/consumatori, bloccanti o non bloccanti.
Io partirei da questa struttura e poi ci costruirei sopra.
__________________
Concluso positivamente con: Kamzata, Ducati82, Arus, TheLastRemnant, ghost driver, alexbull1, DanieleRC5, XatiX
starfred è offline   Rispondi citando il messaggio o parte di esso
Old 26-09-2011, 12:40   #9
banryu79
Senior Member
 
L'Avatar di banryu79
 
Iscritto dal: Oct 2007
Città: Padova
Messaggi: 4131
@starfred: ciao, scusa, ma il tuo precedente esempio mi sembra prono a deadlock, proprio come il codice inzialmente postato da GByTe87; controllo() e leggi() sono entrambi metodi synchronized; cosa succede se un thread ottiene il lock sul monitor dell'istanza condivisa di TestClass e poi non lo rilascia perchè entra in wait?
__________________

As long as you are basically literate in programming, you should be able to express any logical relationship you understand.
If you don’t understand a logical relationship, you can use the attempt to program it as a means to learn about it.
(Chris Crawford)
banryu79 è offline   Rispondi citando il messaggio o parte di esso
Old 26-09-2011, 12:49   #10
starfred
Senior Member
 
Iscritto dal: Jul 2011
Messaggi: 381
E' una proprietà intrinseca nella wait(). Quando un thread esegue la wait() rilascia il monitor ed entra in un'altra coda di attesa. Quando viene eseguita la notify il thread risvegliato rientra in coda al monitor.
__________________
Concluso positivamente con: Kamzata, Ducati82, Arus, TheLastRemnant, ghost driver, alexbull1, DanieleRC5, XatiX
starfred è offline   Rispondi citando il messaggio o parte di esso
Old 26-09-2011, 12:58   #11
banryu79
Senior Member
 
L'Avatar di banryu79
 
Iscritto dal: Oct 2007
Città: Padova
Messaggi: 4131
Quote:
Originariamente inviato da starfred Guarda i messaggi
E' una proprietà intrinseca nella wait(). Quando un thread esegue la wait() rilascia il monitor ed entra in un'altra coda di attesa. Quando viene eseguita la notify il thread risvegliato rientra in coda al monitor.
Sì, hai ragione, mi sono completamente sbagliato.
Meglio ribadirlo a beneficio di GByTe87... chiedo scusa per l'eventuale confusione generata a causa del mio errore.
__________________

As long as you are basically literate in programming, you should be able to express any logical relationship you understand.
If you don’t understand a logical relationship, you can use the attempt to program it as a means to learn about it.
(Chris Crawford)
banryu79 è offline   Rispondi citando il messaggio o parte di esso
Old 26-09-2011, 21:50   #12
GByTe87
Senior Member
 
L'Avatar di GByTe87
 
Iscritto dal: Mar 2007
Città: Milano Beach
Messaggi: 1696
Bene, sono riuscito nel mio intento.

Producer.java

Codice:
public class Producer extends Thread {
	private TestClass test;
	private String filename;

	public Producer(TestClass test, String filename) {
		this.test = test;
		this.filename = filename;
	}

	@Override
	public void run() {
		boolean end = false;

		while (end == false) {
			end = test.check(filename);
			try {
				sleep(1000);
			} catch (InterruptedException exc) {
				System.err.println(exc.getMessage());
			}
		}
	}
}
Consumer.java

Codice:
public class Consumer extends Thread {
	private TestClass test;

	public Consumer(TestClass test) {
		this.test = test;
	}

	@Override
	public void run() {
		boolean end = true;

		while (end)
			end = test.read();
	}
}
TestClass.java

Codice:
import java.io.File;

public class TestClass {

	String fileName;
	private boolean isFileAvailable = false;

	public synchronized boolean read() {
		System.err.println("readin");
		while (isFileAvailable == false) {
			try {
				System.err.println("[read] wait() in | isFileAvailable = " + isFileAvailable);
				wait();
				System.err.println("[read] wait() out | isFileAvailable = " + isFileAvailable);
			} catch (InterruptedException exc) {
				System.err.println(exc.getMessage());
			}
		}

		System.err.println("File pronto!");

		isFileAvailable = false;
		notify();
		System.err.println("readout");
		return isFileAvailable;
	}

	public synchronized boolean check(String filename) {

		System.err.println("checkin");

		this.fileName = filename;
		while (isFileAvailable == true) {
			try {
				System.err.println("[check] wait() in | isFileAvailable = " + isFileAvailable);
				wait();
				System.err.println("[check] wait() out | isFileAvailable = " + isFileAvailable);
			} catch (InterruptedException exc) {
				System.err.println(exc.getMessage());
			}
		}

		File file = new File(fileName);

		if (file.exists()) {
			isFileAvailable = true;
			notify();
		}
		System.err.println("checkout: isFileAvailable = " + isFileAvailable);
		return isFileAvailable;
	}
}
Comprendo che lo sleep non è il massimo dell'eleganza.
Suggermenti su qualcosa di simile da implementare per essere sicuro di aver capito?

Grazie ad entrambi
__________________
~ Cthulhu: MacBookPro 13.3" ~ Azathoth: D510MO

Ultima modifica di GByTe87 : 26-09-2011 alle 21:58.
GByTe87 è offline   Rispondi citando il messaggio o parte di esso
Old 27-09-2011, 08:27   #13
starfred
Senior Member
 
Iscritto dal: Jul 2011
Messaggi: 381
Ciao, la condizione while (isFileAvailable == true) della boolean check(String filename) non verrà mai eseguita per il fatto che il Producer è l'unico che può settare (isFileAvailable = true) ma quando effettua quella operazione esce dal ciclo while (end == false). Quindi, a meno che tu nel main non hai altri Producer, la condizione sopra citata è inutile.
__________________
Concluso positivamente con: Kamzata, Ducati82, Arus, TheLastRemnant, ghost driver, alexbull1, DanieleRC5, XatiX
starfred è offline   Rispondi citando il messaggio o parte di esso
 Rispondi


 Recensione OPPO Find X10 Pro Max: un top di gamma completo con tre fotocamere da 200MP Recensione OPPO Find X10 Pro Max: un top di gam...
WoW Forever provato: il MMORPG che la community chiedeva da anni è arrivato WoW Forever provato: il MMORPG che la community ...
TCL P80 Ultra: con un display AMOLED opaco è una gioia per gli occhi e per le dita TCL P80 Ultra: con un display AMOLED opaco &egra...
HUAWEI MatePad Air recensione: OLED opaco e tastiera dedicata per lavorare meglio HUAWEI MatePad Air recensione: OLED opaco e tast...
NVIDIA RTX Spark: il PC Windows on ARM costruito per l'IA agentica NVIDIA RTX Spark: il PC Windows on ARM costruito...
L'Air Force Research Laboratory ha utili...
L'ONU esprime preoccupazione per le oper...
OpenAI: GPT-6.1 Sol migra il COBOL all'8...
Cyberpunk 2077 porta le mod su console e...
Agenti di IA, per Akamai la sicurezza pa...
Non solo in Europa: Apple dovrà a...
iPhone Duo, il compromesso del display p...
Reolink OMVI 2i Ultra, la videocamera ib...
PowerToys 0.102: con un nuovo tool il mo...
Bose acquisisce Skullcandy per raggiunge...
I videogiochi di Star Wars dovranno sorp...
Cos'è Flint: l'AI locale per la programm...
Perplexity Computer ora gira offline sul...
LG lancia in Italia i nuovi laptop gram ...
Spotify dice addio ai vincoli di Android...
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: 22:36.


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