Cuando se hace uso de programas a veces no importa que este cree más de una instancia al mismo tiempo, por ejemplo podemos ejecutar Paint varias veces y trabajar en paralelo en varios proyectos.
Un programa hecho en java puede ejecutarse las veces que sea al mismo tiempo con tan solo hacer doble clic en los archivos JAR, esto crea una nueva instancia de la aplicación que no es más que una copia exacta del programa en memoria. Pero en ocasiones ya sea por X o Z motivos, se trata de evitar que esto suceda y maneras hay varias, yo te presento una de ellas, la más sencilla.
Explicación.
Para evitar que se creen más de una instancia a la vez de un ejecutable *.JAR, utilizaremos un archivo *.TMP (No confundir con archivos temporales creados con createTempFile ) en donde almacenaremos un valor LONG que corresponde al tiempo actual en milisegundos desde el 01 de enero de 1970, 00:00:00 GMT utilizando el método getTime() del objeto Date, el valor que se obtiene es de la forma «1361471591388».
El valor LONG obtenido se almacenara en un archivo *.TMP que se llamara «miApp.tmp«. Paralelamente se iniciara un proceso que cada cierto tiempo (20 segundos, 1 minuto, 5 minutos, etc) refrescará el valor de miApp.tmp con el tiempo actual en milisegundos, para esto se emplea el objeto «ScheduledExecutorService«.
Cuando se cree una nueva instancia del programa java, este primeramente verificara que el archivo miApp.tmp exista, si no existe, no existe una instancia del programa por tanto crea el archivo *.tmp e inicia la aplicación normalmente, si el archivo SI EXISTE, entonces supone que existe una instancia de la aplicación así que lee el valor del archivo *.tmp y realiza una resta, el resultado de la resta dado en segundos determinara si la instancia del programa esta activo y por tanto no crea una nueva instancia del programa.
Cuando el programa java se cierra, se destruirá el archivo *.TMP
Si me entendieron hasta aquí, entonces una aclaración, :=D , ¿porqué actualizamos el valor del archivo miApp.tmp cada cierto tiempo?, porque puede ocurrir que el programa se cierre inesperadamente y NO se destruya el archivo temporal por tanto, cuando se trate de ejecutar el archivo *.jar, saldrá el aviso «El programa ya esta en ejecución» hasta que el archivo tmp sea eliminado manualmente, para evitar esto, si el archivo TMP ya existe, solamente debemos restamos el valor que tiene y si el resultado es mayor al tiempo que asignamos para la actualización del archivo TMP, damos por hecho de que NO EXISTE UNA INSTANCIA de la aplicación así que creamos una.
Como parece chino lo que estoy diciendo 🙂 una imagen vale mas que mil palabras:
Implementamos el código en una sola clase que llamamos «Control.java»
import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.util.Date; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; import javax.swing.JOptionPane; /** * @web https://www.jc-mouse.net * @author Mouse */ public class Control { //fichero TMP private String appPath = System.getProperties().getProperty("user.dir"); private File fichero = new File( appPath + "\\miApp.tmp"); //tiempo en que se actualiza el fichero TMP private int segundos = 20; /** Constructor de clase */ public Control(){}; /** * Comprueba que archivo TMP exista, sino lo crea e inicia valores */ public boolean comprobar() { if ( fichero.exists() ) { long tiempo = leer();// long res = restarTiempo( tiempo ); if( res < segundos ) { JOptionPane.showMessageDialog(null,"Error: La aplicacion ya esta en ejecución."); return false; } else { programar_tarea(); return true; } } else// no existe fichero { crearTMP(); programar_tarea(); return true; } } /** * Lee el archivo TMP y retorna su valor * @return LONG cantidad de milisegundos */ public long leer() { String linea = "0"; BufferedReader bufferedReader; try { bufferedReader = new BufferedReader( new FileReader( fichero ) ); while(bufferedReader.ready()){ linea = bufferedReader.readLine(); } }catch (IOException e) { System.err.println( e.getMessage() ); } return Long.valueOf(linea).longValue(); } /** * Programa un proceso que se repite cada cierto tiempo */ public void programar_tarea() { ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor(); scheduler.scheduleAtFixedRate( new Runnable() { @Override public void run() { crearTMP(); } }, 1000, segundos * 1000 , TimeUnit.MILLISECONDS ); //comienza dentro de 1 segundo y luego se repite cada N segundos } /** * Crea un archivo TMP con un unico valor, el tiempo en milisegundos */ public void crearTMP() { Date fecha=new Date(); try { BufferedWriter writer = new BufferedWriter(new FileWriter( fichero )); writer.write( String.valueOf( fecha.getTime() ) ); writer.close(); } catch (IOException e) { System.err.println( e.getMessage() ); } } /** * Resta el tiempo expresado en milisegundos * @param tiempoActual el tiempo actual del sistema expresado en milisegundos * @return tiempo el resultado expresado en segundos */ public long restarTiempo( long tiempoActual ) { Date date =new Date(); long tiempoTMP = date.getTime(); long tiempo = tiempoTMP - tiempoActual; tiempo = tiempo /1000; return tiempo; } /** * Elimina el fichero TMP si es que existe */ public void cerrarApp() { if ( fichero.exists() ) { fichero.delete(); } System.exit(0); } }//--> fin clase
Y para poder utilizar esta clase en nuestra aplicación, la implementamos en el MAIN
public class MiApp { public static void main(String[] args) { if( new Control().comprobar() ) { new interfaz().setVisible( true ); } else { System.exit(0); } } }
Para que al cerrar la aplicación se elimine el archivo TMP, se debe implementar el método cerrarApp() en la interfaz de nuestro programa, por ejemplo en un boton:
private void btnCerrarActionPerformed(java.awt.event.ActionEvent evt) { new Control().cerrarApp(); }
Eso es todo
Reproducir archivos de audio en nuestras aplicaciones android. Necesitamos IDE Eclipse y SDK Android instalado Un archiv[...]
En esta oportunidad dejo a considerancion un codigo realizado en Java/Netbeans para recortar una imagen visualmente Vide[...]
En post anteriores vimos lo que son los parámetros IN y los parámetros OUT pero existe otro tipo de parámetro que es la[...]
El Algoritmo de Aldous-Broder llamado así por dos matemáticos, David Aldous and A. Broder (quienes trabajaban en la inve[...]
Los números narcisistas o números de Armstrong son aquellos números enteros positivos cuya suma de las n-ésim[...]
Oi galera, en esta oportunidad les traigo una curiosidad que encontré por casualidad perdiendo el tiempo en Internet, se[...]