PDA

View Full Version : [java] e metodo finalize()


Pipppos
09-04-2003, 09:55
Si puo fare l'ovveride del metodo finalize() di Object?Mi serve eseguire una certa cosa quando il programma viene killato,ho provato ma non sembra andare :confused: :rolleyes:

soalle
09-04-2003, 11:59
Non ho mai provato a farlo, ma si dovrebbe riuscire (naturalmente richiamando un bel super.finalize(); )... considera che il metodo non viene richiamato in maniera deterministica ma solo quando inizia a frullare il gc...
A questo punto ho qualche dubbio sul fatto che il gc venga richiamato nel momento in cui viene terminato il programma (d'altra parte viene rilasciata tutta la memoria assegnata a quel processo)....

quindi prova a richiamarlo tu (mi pare con Runtime.gc(); oppure con RunTime.runFinalization();)

Facci sapere che sono curioso... :D

soalle
09-04-2003, 12:06
Ah... mi sembra ovvio ma è meglio specificare che...
naturalmente perché il gc possa fare il suo lavoro non ci devono essere più riferimenti all'oggetto in questione

Pipppos
09-04-2003, 12:26
Ho provato ma il metodo finalize() che ho ridefinito non viene richiamato per una uscita anomala dal programma ma soltanto se si termina con una System.exit,a me invece serve che il metodo in questione venga eseguito quando il programma viene killato. :confused: :confused:

soalle
09-04-2003, 13:09
Non penso ci sia il modo di intercettare questo evento proveniente dall'OS...
Devi cercare una strada alternativa...
Magari se spieghi meglio il problema e le risorse che devi deallocare si riesce a capire meglio l'eventuale soluzione...

Considera inoltre che penso che neppure in Linux sia possibile intercettare il kill -9...

Pipppos
09-04-2003, 14:13
Il programma ha un thread principale che contiene tutto il corpo del programma,resta in background (non ha interfaccia) ed emette dei messaggi tramite dialogbox in corrispondenza di determinati eventi.
All'attivazione genera un file che mi serve x controllare che altre istanze non vengano eseguite,il file dovrebbe poi essere cancellato all'uscita.Il problema è che il prog non ha una funzione di uscita quindi verrebbe killato dall'arresto di windows,avevo quindi pensato di cancellare il file nel metodo finalize() :rolleyes: :rolleyes:

soalle
09-04-2003, 14:25
Il file ti serve per creare una sola istanza del thread a livello di programmazione (cioé possibilità di istanziare un solo oggetto Thread) oppure ti serve per evitare che un utente lanci due volte il programma?

Pipppos
09-04-2003, 16:03
Mi serve per evitare che l'utente lanci n volte il programma xchè se lo facesse esisterebbero n istanze del programma e quindi in concomitanza all'evento n dialogbox. :rolleyes:

soalle
09-04-2003, 17:22
Allora prova a vedere le classi FileLock e FileChannel del package java.nio.*

Sono presenti solo dalla versione 1.4.x del jdk ma penso che dovrebbero fare al caso tuo...

... se trovi la soluzione naturalmente posta...

PGI
09-04-2003, 17:49
Nel corso della discussione ho un po' perso il filo del discorso per cui prima di intromettermi avrei bisogno di una conferma:

in pratica tu vorresti eseguire del codice nel momento in cui la JVM viene chiusa e uno shutdownhook non ti basta perchè non gestisce il "killing" dell'applicazione da parte del sistema operativo?

Se la risposta è "NO" allora non ho capito niente, se è "SI" allora possiamo farci qualcosa.

Fammi sapere e in caso vediamo che si può fare.

Ciao.

soalle
09-04-2003, 17:51
Cosa intendi per shutdownhook??? :confused:
Mi piacerebbe esplorare questa cosa... intendi interagire con gli hook del sistema operativo tramite jni?

PGI
09-04-2003, 18:04
E' un "pezzo" di java che si usa sopratutto con i database, per evitare di lasciare aperte connessioni nel caso in cui il programma venga terminato brutalmente (ad esempio via TaskManger).

L'esempio più semplice è il metodo

[File].deleteOnExit(). Quando la jvm viene chiusa il file viene cancellato.

Quello che fa quel metodo è un'implementazione di "addShutDownHook(Thread t)" della classe Runtime.


...
Runtime.getRuntime().addShutDownHook(shutDown);
...
class ShutDown extends Thread {
public void run() {
//...
//operazioni "dell'ultimo minuto"
//...
}
}


Il problema è che funziona solo se c'è una chiamata al metodo Runtime.exit(int), cioè se l'applicazione termina regolarmente.

Per gestire "uscite brutali" si usa allora un gestore di segnali ma la faccenda diventa un po' più laboriosa perchè fa parte di un pacchetto (sun.misc) presente nel JDK ma non documentato.

soalle
09-04-2003, 19:44
Interessante.... e buono a sapersi... :D

PGI
09-04-2003, 20:19
Interessante sì, ma poco "Java-style" perchè è platform-dependent e, come tutti i package sun.qualcosa, non è garantita la futura implementazione :cry:

Pippos non dà segni di vita (scherzo), lo prendo per un "SI" e posto un po' di codice (domani non sono on-line e magari deve trovare una soluzione in fretta)


import sun.misc.*;
import java.io.*;

public class Prova {
private ShutdownHandler shutDown=new ShutdownHandler();
private ShutDownHook hook=new ShutDownHook();
private boolean nostop=true;
private File tempFile=null;

Prova() {
Signal.handle(new Signal("INT"),shutDown); //CTRL-C
Signal.handle(new Signal("TERM"),shutDown); //CHIUSURA DEL SISTEMA

//Signal.handle(new Signal("KILL"),shutDown);
//fino al JDK v. 1.3 SHUTDOWN DA TASK MANAGER

Runtime.getRuntime().addShutdownHook(hook);

tempFile=new File("f:\\cancellami.txt");
try {
tempFile.createNewFile();
} catch (IOException ex) {
System.out.println(ex);
System.exit(0);
}

//un ciclo infinito per verificare che funzioni
//l'intercettazione dei segnali del sistema operativo
while(nostop) {/*...*/}
}

public static void main(String[] args) {
new Prova();
}

class ShutdownHandler implements SignalHandler {
public void handle(Signal signal) {
System.exit(0); //questo richiama l'hook
}
}

class ShutDownHook extends Thread {
public void run() {
System.out.println("Cancello il file temporaneo");
if(tempFile.exists()) {
tempFile.delete();
}
System.out.println("il programma verrà chiuso tra 2 secondi");
try {
Thread.currentThread().sleep(2000);
} catch (Exception e) {
System.out.println(e);
}
}
}
}


La classe qui sopra crea un file temporaneo e lo cancella quando la JVM viene terminata con il comando System.exit(0);la classe ShutDownHandler "forza" una chiamata all'uscita "naturale" della JVM anche quando Windows cerca di interromperne l'esecuzione allo spegnimento del sistema (il segnale in questo caso è quel "TERM") oppure quando viene premuta la combinazione CRTL-C ("INT"). Dalla versione 1.4 del JRE il segnale "KILL" sembra non funzionare più (corrisponde all'interruzione forzata da task manager) e non è una cattiva idea per ovvi motivi di sicurezza ;) .
La chiusura effettiva della JVM è poi gestita dal Thread ShutDownHook che cancella il file "temporaneo".

Il pessimo ciclo infinito while e il suo indegno booleano "nostop" servono solo per simulare un'applicazione che gira costantemente.

Per una versione UNIX del programma i segnali dovrebbero essere "INT" "TERM" "QUIT" e (forse) anche "KILL"

Fammi sapere se è servito a qualcosa

Ciao.

Pipppos
10-04-2003, 09:34
Grazissime PGI la tua soluzione funziona bene e fà proprio a caso mio :) :) :) :D :D

mone.java
07-09-2010, 16:27
Interessante sì, ma poco "Java-style" perchè è platform-dependent e, come tutti i package sun.qualcosa, non è garantita la futura implementazione :cry:

Pippos non dà segni di vita (scherzo), lo prendo per un "SI" e posto un po' di codice (domani non sono on-line e magari deve trovare una soluzione in fretta)


import sun.misc.*;
import java.io.*;

public class Prova {
private ShutdownHandler shutDown=new ShutdownHandler();
private ShutDownHook hook=new ShutDownHook();
private boolean nostop=true;
private File tempFile=null;

Prova() {
Signal.handle(new Signal("INT"),shutDown); //CTRL-C
Signal.handle(new Signal("TERM"),shutDown); //CHIUSURA DEL SISTEMA

//Signal.handle(new Signal("KILL"),shutDown);
//fino al JDK v. 1.3 SHUTDOWN DA TASK MANAGER

Runtime.getRuntime().addShutdownHook(hook);

tempFile=new File("f:\\cancellami.txt");
try {
tempFile.createNewFile();
} catch (IOException ex) {
System.out.println(ex);
System.exit(0);
}

//un ciclo infinito per verificare che funzioni
//l'intercettazione dei segnali del sistema operativo
while(nostop) {/*...*/}
}

public static void main(String[] args) {
new Prova();
}

class ShutdownHandler implements SignalHandler {
public void handle(Signal signal) {
System.exit(0); //questo richiama l'hook
}
}

class ShutDownHook extends Thread {
public void run() {
System.out.println("Cancello il file temporaneo");
if(tempFile.exists()) {
tempFile.delete();
}
System.out.println("il programma verrà chiuso tra 2 secondi");
try {
Thread.currentThread().sleep(2000);
} catch (Exception e) {
System.out.println(e);
}
}
}
}


La classe qui sopra crea un file temporaneo e lo cancella quando la JVM viene terminata con il comando System.exit(0);la classe ShutDownHandler "forza" una chiamata all'uscita "naturale" della JVM anche quando Windows cerca di interromperne l'esecuzione allo spegnimento del sistema (il segnale in questo caso è quel "TERM") oppure quando viene premuta la combinazione CRTL-C ("INT"). Dalla versione 1.4 del JRE il segnale "KILL" sembra non funzionare più (corrisponde all'interruzione forzata da task manager) e non è una cattiva idea per ovvi motivi di sicurezza ;) .
La chiusura effettiva della JVM è poi gestita dal Thread ShutDownHook che cancella il file "temporaneo".

Il pessimo ciclo infinito while e il suo indegno booleano "nostop" servono solo per simulare un'applicazione che gira costantemente.

Per una versione UNIX del programma i segnali dovrebbero essere "INT" "TERM" "QUIT" e (forse) anche "KILL"

Fammi sapere se è servito a qualcosa

Ciao.

Ciao PGI scusa se ti rompo ma ho provato ad usare questo frammento di codice e con eclipse mi dice:

Multiple markers at this line
- Access restriction: The constructor Signal(String) is not accessible due to restriction on required library /usr/lib/jvm/
java-6-sun-1.6.0.20/jre/lib/rt.jar
- Access restriction: The type Signal is not accessible due to restriction on required library /usr/lib/jvm/java-6-
sun-1.6.0.20/jre/lib/rt.jar
- Access restriction: The method handle(Signal, SignalHandler) from the type Signal is not accessible due to
restriction on required library /usr/lib/jvm/java-6-sun-1.6.0.20/jre/lib/rt.jar
- Access restriction: The type Signal is not accessible due to restriction on required library /usr/lib/jvm/java-6-
sun-1.6.0.20/jre/lib/rt.jar

Cosa significa??? Quelle librerie sono forse state deprecate??? Esistono delle alternative??

Grazie mille!!!

banryu79
07-09-2010, 17:05
Cosa significa??? Quelle librerie sono forse state deprecate??? Esistono delle alternative??

Grazie mille!!!
Ammazza se hai risvegliato i morti! (si fa per dire) :D
Sviluppi con Eclipse? Guarda qui (http://ubuntuforums.org/showthread.php?t=569113)