2010-09-15 7 views

Respuesta

1

Puede usar una dirección de socket del servidor como un bloqueo exclusivo.

Cuando se inicia la aplicación, intentará vincular el socket del servidor a una dirección predefinida. Si eso falla, significa que una instancia anterior de la aplicación se está ejecutando y es propietaria de esa dirección. Haga ping a esa dirección para decirle al propietario que salga.

serverSocket = new ServerSocket(localhost:8888) 
if success, 
    start ServerSocketListeningThread 
else 
    socket = new Socket(localhost:8888) 
    socket.close(); 
    sleep(100); 
    repeat attempt of binding server socket 

ServerSocketListeningThread 
    serverSocket.accept(); //block until someone connects 
    System.exit(); 

Es fácil de apagar su aplicación desde la línea de comandos

telnet localhost 8888 
2

Si la aplicación se inicia utilizando Java Web Start, puede acceder al servicio SingleInstanceService de la API JNLP. Aquí hay un demo. of the SIS.

2

Siempre puede tener un archivo de bloqueo y asegurarse de que su programa finalice si no puede obtener un bloqueo exclusivo sobre él.

Referencia

+0

Simplemente curioso ... si la aplicación. que tiene la cerradura terminada digamos kill -9 en linux, ¿la cerradura se liberaría después de que JVM haya terminado? –

+0

No lo he probado, pero creo que sí, sí. – zigdon

2

supongo que estamos hablando de un programa Java independiente, cada instancia en ejecución en su propia JVM. En ese caso, aquí están las opciones que veo para ti:

  • Set-up RMI llamadas entre sus programas (Se parece un poco exagerado)
  • Trate cajo (no he probado a mí mismo, pero parece que resuelve su problema)
  • Si está en Unix/Linux, invoque el script del shell para eliminar el proceso existente
  • Use una solución casera, por ejemplo, cree un archivo con un nombre único en el sistema de archivos cada vez que su programa inicia y elimina cualquier otro archivo presente en el mismo directorio. Luego, compruebe periódicamente que el archivo adjunto a la instancia actual todavía está allí (utilizando un temporizador), si no lo es, finalice la JVM actual.
0

Sólo tiene que llamar al método Exiter.isAlone() en el método main(). Mata al anterior. (Es una implementación de la solución de Irreputable, gracias) Un socket de servidor está escuchando en el puerto 8181 (en este ejemplo). Si recibe alguna solicitud, existe y detiene jvm (System.exist()). Cuando inicia una nueva aplicación, intenta instalar el escucha de socket. Si está bien, si el puerto está ocupado, envía una solicitud para detenerlo. El método isAlone() está esperando el asesinato del anterior. Si lo llamas en la primera línea del método principal (String [] s), estás seguro de que se eliminó el anterior.

public class Exiter implements Runnable { 

    private static final Exiter instance = new Exiter(); 
    private ServerSocket serverSocket; 
    private int port = 8181; 
    private boolean bStarting = true; 

    private Exiter() { 
     (new Thread(this)).start(); 
    } 

    @Override 
    public void run() { 

     while (bStarting) { 
      try { 
       serverSocket = new ServerSocket(port); 
       bStarting = false; 
       awake(); 
      } catch (IOException e) { 
       System.err.println("Exiter : "+e.getMessage()+" port "+port); 
       openSocketKillRequest(); 
       try { 
        Thread.sleep(500); 
       } catch (InterruptedException e1) { 
        e1.printStackTrace(); 
       } 
      } 
     } 
     try { 
      Socket s = serverSocket.accept();// Ca bloque 
      System.err.println("Kimll Request from :" + s.getRemoteSocketAddress()); 
      System.exit(0); 
     } catch (IOException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 

    } 

    private void openSocketKillRequest() { 
     try { 
      System.err.println("Send request kill previous"); 
      Socket socket = new Socket("localhost", port); 
      socket.close(); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
    } 

    public static Exiter getInstance() { 
     return instance; 
    } 

    private synchronized void awake(){ 
     notifyAll(); 
    } 

    public synchronized boolean isAlone() { 
     if(bStarting){ 
      try { 
       wait(); 
      } catch (InterruptedException e) { 

       e.printStackTrace(); 
      } 
     } 
     return true; 
    } 
} 
Cuestiones relacionadas