Evitar que una aplicación java se ejecute mas de una vez

Buenas tardes, antes que nada les felicito por su sitio que es de gran ayuda cuando uno está "naufragando en internet en busca de información" mi consulta es la siguiente:

Tengo un aplicación estándar en java de tipo consola, pero necesito evitar que se ejecute más de una vez al mismo tiempo, ya que cuando lo hace afecta a la funcionalidad para la cual fue desarrollada (envió de trx) y cada instancia los hace más de una vez dando como resultado el duplicado de envió por cada trx.

Cabe mencionar que la aplicación tiene la lógica necesaria por ella misma, para no duplicar el envió de las mismas (actualiza estatus), pero se da el caso si otra instancia de mi mismo programa es iniciada casi inmediatamente, lo cual ocasiona que ambas inicialmente detecten que ciertas trx no se han enviado y ambas lo carguen en una cola donde simplemente envía y actualizan estados de las trx.

Básicamente mi pregunta es: ¿Cómo puedo detectar que ya se está ejecutando un instancia de mi aplicación?

De antemano gracias por sus respuestas y/o comentarios

saludos

Gustavo BECMART.

Opciones de visualización de comentarios

Seleccione la forma que prefiera para mostrar los comentarios y haga clic en «Guardar las opciones» para activar los cambios.
Imagen de domix

algunas personas para este

algunas personas para este tipo de cosas lo que hacen por ejemplo es abrir un Serversocket, de tal manera que si alguna otra instancia de tu aplicación intenta abrir el serversocket, pues le truena ya que el puerto esta ocupado. Este tipo de solución tiene la bronca de los firewall de las maquinas. Pero pues es una opción

Otra opción es escribir un archivo lck cuando tu aplicación se abre y borrarlo cuando termina, de nuevo tu aplicación verifica cuando arranca la existencia de este archivo.

Saludos.

Ya lo habia contemplado,

Ya lo habia contemplado, pero queria saber si existia otra manera mas elegante

De todas formas gracias por tu pronta respuesta.

saludos

Patron de diseño

Busca sobre el patron de diseño Singleton, creo que puede ayudarte en lo que quieres hacer.

Imagen de domix

El patrón de diseño

El patrón de diseño Singleton no funciona ya que el singleton solo funcionan en una instancia de la JVM a menos que tengas en cluster la JVM como con Terracota.

Imagen de domix

di la verdad con sencillez y

di la verdad con sencillez y la elegancia déjasela al sastre

Imagen de ezamudio

Elegante o rebuscada?

Esas dos soluciones son bastante comunes (el archivo de bloqueo y el server socket) porque son sencillas, y son rápidas. Lo primero que haces en tu programa es ver si existe el archivo de bloqueo, y si es asi, terminar. Si tu problema es solamente que no corra dos veces el mismo programa en la máquina, eso debe ser suficiente:
Si no existe, crearlo. Tendrían que correr los dos programas exactamente al mismo tiempo para que ambos vieran que no esta el archivo y ambos lo crearan...
Con el caso del server socket, simplemente lo primero que haces es crear el server socket, darle bind a un puerto, y cachar la BindException (si ocurre dicha excepción debes terminar tu programa porque ya está el otro corriendo ahi). Pero tienes que escoger bien el puerto para que no sea algo que otro programa vaya a usar. No te preocupes por el firewall porque simplemente nunca vas a recibir nada en el socket, solamente necesitas poder abrirlo.
Estas dos soluciones son sencillas. Otra podría ser crear un ejecutable ya directo de windows o lo que sea que estés usando y configurarlo para que solamente corra una vez (hay programas que si los corres dos veces, la segunda vez te trae el primer programa al frente en vez de correr una segunda instancia). No recuerdo el nombre de una herramienta gratuita que crea ejecutables para Windows que invocan un programa de Java.
Pero todas las soluciones anteriores solamente evitan que corra el programa dos veces en el mismo equipo... si quieres que el programa corra una sola vez en todo el sitio (en caso que haya varios programas que hagan esto), entonces pues tienes que usar algun recurso externo. Supongo que las transacciones que lees marcadas como pendientes, estan en una base de datos... hay varias opciones, puedes leerlas dentro de una transacción con un SELECT FOR UPDATE y eso va a bloquear los registros a nivel base de datos; ningún otro proceso los podrá ver. Incluso si corre otra instancia del programa en otra máquina, se quedará esperando a poder leer dichos registros; cuando el primer programa termine y actualice su status, el query no le devolverá esos mismos registros al segundo programa.
O si no puedes bloquear los registros, entonces lo primero que haces es abrir una transacción en la base de datos, leer un registro de una tabla y cambiar un valor (por ejemplo un 0 a un 1) y das commit, luego haces todo tu proceso normal, y al terminar, vuelves a modificar el 1 a 0 dentro de una transaccion. Si un segundo programa quiere hacer lo mismo, la base de datos lo bloquea hasta que termine de modificarse dicho registro (solamente va a permitir una lectura de ese registro a la vez, si configuras bien tu transacción); cuando leas el registro, si trae algo distinto de 0 entonces no haces nada. Pero tienes que tener mucho cuidado con este último mecanismo porque si el primer programa termina de manera anormal y no regresa a 0 el valor, cuando lo corras nuevamente no va a hacer nada (porque el valor está todavía en 1 en la base de datos); tendrias que regresarlo a 0 manualmente y luego volverlo a correr.
Otra opción es que en vez de 0 y 1 simplemente actualices el registro con la fecha en que estás corriendo el programa; si el segundo programa lee la fecha y ha pasado muy poco tiempo (solo unos segundos o unos minutos o el tiempo que tú decidas), entonces no hace nada el programa. Así no tienes que actualizar nada al final y de hecho aseguras que solamente se ejecuta cada X tiempo tu proceso, aunque el scheduler estuviera mal o un usuario quiera correr el programa cada segundo.

Given the choice of dancing pigs and security, users will choose dancing pigs, every single time.
Steve Riley

Imagen de poloche

file

He usado la solucion del file y tiene buen resultado gracias.