Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.java.programmer > #20937

Re: single instance

From Knute Johnson <nospam@knutejohnson.com>
Newsgroups comp.lang.java.programmer
Subject Re: single instance
Date 2013-01-03 19:31 -0800
Organization A noiseless patient Spider
Message-ID <kc5iep$ut1$1@dont-email.me> (permalink)
References <iah6e8hb9ssp4q46ukh3scb81bjb9fdq1k@4ax.com> <1rxjd74kjrhfc.mdbq9v09dxbn$.dlg@40tude.net>

Show all headers | View raw


On 1/3/2013 12:55 AM, Peter Duniho wrote:
> As far as the sockets approach goes, you might be able to avoid the need of
> dealing with a magic file or hard-coded socket port by using UDP multicast
> with the SO_REUSEADDR option. This would allow your program to join to a
> multicast port without interference from other programs, ensuring it's
> ready to receive a UDP datagram sent on the channel from a new instance
> searching for a prior existing instance.
>
> Unfortunately, unlike the exclusive-create option available for a file,
> there's no such built-in support for resolving race conditions in the
> socket-based approach. Unless you are willing to go without a solution, or
> are confident you can correctly design and implement a solution, you may
> want to stick with the more user-driven approaches suggested.
>
> But it's there in case you want to try. :)
>
> Pete

I'm not sure how you could do this without establishing what group and 
port your were going to use before hand.  But maybe that isn't what you 
were saying.

So what do you think of this implementation?  I did try to start two 
copies with a batch file and I could get them to fail on occasion.  I 
don't think it would be possible for a user to start two copies 
simultaneously though.

Thanks,

knute...

import java.awt.*;
import java.io.*;
import java.lang.reflect.*;
import java.net.*;
import java.nio.charset.*;
import java.util.*;
import javax.swing.*;

public class Exclusive implements Runnable {
     private final long myTime;
     private final MulticastSocket socket;
     private final InetAddress group;
     private final int port;

     private volatile boolean runFlag;
     private volatile Thread thread;

     public Exclusive(String ipStr, String portStr) throws IOException {
         myTime = System.currentTimeMillis();

         group = InetAddress.getByName(ipStr);
         port = Integer.parseInt(portStr);

         socket = new MulticastSocket(port);
         socket.joinGroup(group);
     }

     public void start() throws IOException {
         if (thread == null || !thread.isAlive()) {
             runFlag = true;
             thread = new Thread(this);
             thread.start();

             // send out my time
             String str = Long.toString(myTime);
             byte[] buf = str.getBytes(StandardCharsets.US_ASCII);
             DatagramPacket dp =
              new DatagramPacket(buf,buf.length,group,port);
             socket.send(dp);
         }
     }

     @Override public void run() {
         while (runFlag) {
             try {
                 // receive their time
                 byte[] buf = new byte[64];
                 DatagramPacket dp = new DatagramPacket(buf,buf.length);
                 socket.receive(dp);
                 String timeStr = new String(dp.getData(),dp.getOffset(),
                  dp.getLength(),StandardCharsets.US_ASCII);
                 long theirTime = Long.parseLong(timeStr);
                 // if we are seeing our own packet, do nothing
                 if (theirTime == myTime) {
                 // if their time is before my time, we need to shut down
                 } else if (theirTime < myTime) {
                     stop();
                     shutdownHook();
                 // if their time is after my time, send out my time
                 } else if (theirTime > myTime) {
                     String str = Long.toString(myTime);
                     buf = str.getBytes(StandardCharsets.US_ASCII);
                     dp = new DatagramPacket(buf,buf.length,group,port);
                     socket.send(dp);
                 }
             } catch (IOException|NumberFormatException ex) {
                 ex.printStackTrace();
                 stop();
             }
         }
     }

     private void stop() {
         if (thread != null && thread.isAlive()) {
             runFlag = false;
             if (socket != null)
                 socket.close();
         }

         // signal the waitFor() method to stop waiting
         synchronized (this) {
             notify();
         }
     }

     // wait for two seconds to delay program startup until we have
     //  time to determine if there is another copy running.
     //  returns true if no other copy is running.
     public synchronized boolean waitFor() throws InterruptedException {
         wait(2000);

         return runFlag;
     }

     public void shutdownHook() {
         // can't use invokeLater()
         try {
             EventQueue.invokeAndWait(new Runnable() {
                 public void run() {
                     JOptionPane.showMessageDialog(null,
                      "Another Copy of this Program is Already Running",
                      "Start Inhibited",JOptionPane.ERROR_MESSAGE);
                 }
             });
         } catch (InterruptedException|InvocationTargetException ex) {
             ex.printStackTrace();
         }
     }

     public static void main(String[] args) {
         try {
             Exclusive e = new Exclusive("227.228.229.230","23222");
             e.start();
             if (e.waitFor())
                 System.out.println("no other copy running!");
             else
                 System.out.println("another copy is running");

         } catch (IOException|InterruptedException ex) {
             // probably don't want to start if you get an exception either
             ex.printStackTrace();
         }
     }
}

-- 

Knute Johnson

Back to comp.lang.java.programmer | Previous | NextPrevious in thread | Next in thread | Find similar | Unroll thread


Thread

single instance Roedy Green <see_website@mindprod.com.invalid> - 2013-01-01 12:23 -0800
  Re: single instance Arne Vajhøj <arne@vajhoej.dk> - 2013-01-01 16:40 -0500
    Re: single instance Robert Tomsick <robert+usenet@tomsick.net> - 2013-01-03 01:20 -0500
  Re: single instance Peter Duniho <NpOeStPeAdM@NnOwSlPiAnMk.com> - 2013-01-03 00:55 -0800
    Re: single instance Knute Johnson <nospam@knutejohnson.com> - 2013-01-03 19:31 -0800
      Re: single instance Peter Duniho <NpOeStPeAdM@NnOwSlPiAnMk.com> - 2013-01-03 19:49 -0800
      Re: single instance Peter Duniho <NpOeStPeAdM@NnOwSlPiAnMk.com> - 2013-01-03 19:56 -0800
        Re: single instance Twirlip of the Mists <twirlip@killfile.me.now.invalid> - 2013-01-04 12:18 -0500
          Re: single instance Peter Duniho <NpOeStPeAdM@NnOwSlPiAnMk.com> - 2013-01-04 10:22 -0800
            Re: single instance Twirlip of the Mists <twirlip@killfile.me.now.invalid> - 2013-01-04 13:44 -0500
              Re: single instance Peter Duniho <NpOeStPeAdM@NnOwSlPiAnMk.com> - 2013-01-04 11:03 -0800
                Re: single instance Twirlip of the Mists <twirlip@killfile.me.now.invalid> - 2013-01-04 14:12 -0500
              Re: single instance Arne Vajhøj <arne@vajhoej.dk> - 2013-01-05 21:56 -0500
                Re: single instance Twirlip of the Mists <twirlip@killfile.me.now.invalid> - 2013-01-06 19:22 -0500
                Re: single instance Arne Vajhøj <arne@vajhoej.dk> - 2013-01-06 20:23 -0500
                Re: single instance Twirlip of the Mists <twirlip@killfile.me.now.invalid> - 2013-01-06 20:43 -0500
                Re: single instance Arne Vajhøj <arne@vajhoej.dk> - 2013-01-06 20:47 -0500
                Re: single instance Twirlip of the Mists <twirlip@killfile.me.now.invalid> - 2013-01-06 20:51 -0500
                Re: single instance Arne Vajhøj <arne@vajhoej.dk> - 2013-01-06 20:24 -0500
                Re: single instance Twirlip of the Mists <twirlip@killfile.me.now.invalid> - 2013-01-06 20:46 -0500
                Re: single instance Arne Vajhøj <arne@vajhoej.dk> - 2013-01-06 20:58 -0500
                Re: single instance Twirlip of the Mists <twirlip@killfile.me.now.invalid> - 2013-01-06 21:08 -0500
                Re: single instance Arne Vajhøj <arne@vajhoej.dk> - 2013-01-06 21:19 -0500
                Re: single instance Twirlip of the Mists <twirlip@killfile.me.now.invalid> - 2013-01-06 21:31 -0500
                Re: single instance Arne Vajhøj <arne@vajhoej.dk> - 2013-01-06 21:41 -0500
                Re: single instance Twirlip of the Mists <twirlip@killfile.me.now.invalid> - 2013-01-06 22:00 -0500
                Re: single instance Arne Vajhøj <arne@vajhoej.dk> - 2013-01-06 22:11 -0500
                Re: single instance Twirlip of the Mists <twirlip@killfile.me.now.invalid> - 2013-01-07 00:23 -0500
                Re: single instance Arne Vajhøj <arne@vajhoej.dk> - 2013-02-24 18:20 -0500
                Re: single instance Joshua Cranmer <Pidgeot18@verizon.invalid> - 2013-01-06 21:39 -0600
                Re: single instance Twirlip of the Mists <twirlip@killfile.me.now.invalid> - 2013-01-07 00:30 -0500
                Re: single instance lipska the kat <lipskathekat@yahoo.co.uk> - 2013-01-07 08:53 +0000
                Re: single instance Arne Vajhøj <arne@vajhoej.dk> - 2013-02-24 18:18 -0500
                Re: single instance lipska the kat <"nospam at neversurrender dot co dot uk"> - 2013-02-25 08:31 +0000
                Re: single instance Arne Vajhøj <arne@vajhoej.dk> - 2013-02-24 18:17 -0500
                Re: single instance Lew <lewbloch@gmail.com> - 2013-01-06 17:32 -0800
                Re: single instance Twirlip of the Mists <twirlip@killfile.me.now.invalid> - 2013-01-06 20:47 -0500
                Re: single instance Arne Vajhøj <arne@vajhoej.dk> - 2013-01-06 20:53 -0500
                Re: single instance Twirlip of the Mists <twirlip@killfile.me.now.invalid> - 2013-01-06 21:01 -0500
          Re: single instance Arne Vajhøj <arne@vajhoej.dk> - 2013-01-05 21:59 -0500
            Re: single instance Twirlip of the Mists <twirlip@killfile.me.now.invalid> - 2013-01-06 19:34 -0500
              Re: single instance Arne Vajhøj <arne@vajhoej.dk> - 2013-01-06 20:00 -0500
  Re: single instance Roedy Green <see_website@mindprod.com.invalid> - 2013-01-03 07:12 -0800
    Re: single instance Peter Duniho <NpOeStPeAdM@NnOwSlPiAnMk.com> - 2013-01-03 09:56 -0800
      Re: single instance Martin Gregorie <martin@address-in-sig.invalid> - 2013-01-03 21:05 +0000
        Re: single instance Martin Gregorie <martin@address-in-sig.invalid> - 2013-01-03 22:08 +0000
        Re: single instance "Chris Uppal" <chris.uppal@metagnostic.REMOVE-THIS.org> - 2013-01-05 12:48 +0000
          Re: single instance Martin Gregorie <martin@address-in-sig.invalid> - 2013-01-05 17:43 +0000
            Re: single instance Peter Duniho <NpOeStPeAdM@NnOwSlPiAnMk.com> - 2013-01-05 09:49 -0800
            Re: single instance Twirlip of the Mists <twirlip@killfile.me.now.invalid> - 2013-01-05 13:02 -0500
              Re: single instance Martin Gregorie <martin@address-in-sig.invalid> - 2013-01-05 20:29 +0000
                Re: single instance Roedy Green <see_website@mindprod.com.invalid> - 2013-01-05 19:07 -0800
                Re: single instance Twirlip of the Mists <twirlip@killfile.me.now.invalid> - 2013-01-06 20:04 -0500
            Re: single instance Arne Vajhøj <arne@vajhoej.dk> - 2013-01-05 21:40 -0500
    Re: single instance Arne Vajhøj <arne@vajhoej.dk> - 2013-01-05 22:10 -0500
      Re: single instance Knute Johnson <nospam@knutejohnson.com> - 2013-01-05 19:49 -0800
        Re: single instance Arne Vajhøj <arne@vajhoej.dk> - 2013-01-05 23:09 -0500
          Re: single instance Arne Vajhøj <arne@vajhoej.dk> - 2013-01-06 11:00 -0500
            Re: single instance Lew <lewbloch@gmail.com> - 2013-01-06 09:41 -0800
              Re: single instance Arne Vajhøj <arne@vajhoej.dk> - 2013-01-06 20:41 -0500
        Re: single instance Roedy Green <see_website@mindprod.com.invalid> - 2013-01-15 22:51 -0800
          Re: single instance Roedy Green <see_website@mindprod.com.invalid> - 2013-01-15 23:12 -0800
            Re: single instance Peter Duniho <NpOeStPeAdM@NnOwSlPiAnMk.com> - 2013-01-15 23:49 -0800
          Re: single instance Roedy Green <see_website@mindprod.com.invalid> - 2013-01-15 23:16 -0800
            Re: single instance Peter Duniho <NpOeStPeAdM@NnOwSlPiAnMk.com> - 2013-01-15 23:52 -0800
            Re: single instance Knute Johnson <nospam@knutejohnson.com> - 2013-01-16 08:46 -0800
              Re: single instance Roedy Green <see_website@mindprod.com.invalid> - 2013-01-16 10:46 -0800
                Re: single instance markspace <markspace@nospam.nospam> - 2013-01-16 13:01 -0800
                Re: single instance Knute Johnson <nospam@knutejohnson.com> - 2013-01-16 17:10 -0800
          Re: single instance Roedy Green <see_website@mindprod.com.invalid> - 2013-01-15 23:50 -0800
            Re: single instance Peter Duniho <NpOeStPeAdM@NnOwSlPiAnMk.com> - 2013-01-16 00:13 -0800
              Re: single instance Roedy Green <see_website@mindprod.com.invalid> - 2013-01-16 02:48 -0800
                Re: single instance Peter Duniho <NpOeStPeAdM@NnOwSlPiAnMk.com> - 2013-01-16 07:28 -0800
                Re: single instance Roedy Green <see_website@mindprod.com.invalid> - 2013-01-16 10:46 -0800
                Re: single instance Peter Duniho <NpOeStPeAdM@NnOwSlPiAnMk.com> - 2013-01-16 16:53 -0800
                Re: single instance Roedy Green <see_website@mindprod.com.invalid> - 2013-01-16 23:44 -0800
                Re: single instance Peter Duniho <NpOeStPeAdM@NnOwSlPiAnMk.com> - 2013-01-17 07:03 -0800
                Re: single instance Roedy Green <see_website@mindprod.com.invalid> - 2013-01-17 14:25 -0800
                Re: single instance Peter Duniho <NpOeStPeAdM@NnOwSlPiAnMk.com> - 2013-01-17 16:31 -0800
                Re: single instance Roedy Green <see_website@mindprod.com.invalid> - 2013-01-17 22:11 -0800
                Re: single instance Roedy Green <see_website@mindprod.com.invalid> - 2013-01-17 22:36 -0800
              Re: single instance Arne Vajhøj <arne@vajhoej.dk> - 2013-01-16 13:34 -0500
          Re: single instance Knute Johnson <nospam@knutejohnson.com> - 2013-01-16 08:45 -0800
          Re: single instance Arne Vajhøj <arne@vajhoej.dk> - 2013-01-16 13:29 -0500
            Re: single instance Knute Johnson <nospam@knutejohnson.com> - 2013-01-16 17:14 -0800
              Re: single instance Arne Vajhøj <arne@vajhoej.dk> - 2013-01-16 20:20 -0500
              Re: single instance Roedy Green <see_website@mindprod.com.invalid> - 2013-01-16 23:52 -0800
              Re: single instance Roedy Green <see_website@mindprod.com.invalid> - 2013-01-17 01:44 -0800
        Re: single instance Roedy Green <see_website@mindprod.com.invalid> - 2013-01-18 01:47 -0800
          Re: single instance Knute Johnson <nospam@knutejohnson.com> - 2013-01-18 20:50 -0800
            Re: single instance Roedy Green <see_website@mindprod.com.invalid> - 2013-01-20 00:53 -0800
              Re: single instance Lew <lewbloch@gmail.com> - 2013-01-20 12:00 -0800
                Re: single instance Knute Johnson <nospam@knutejohnson.com> - 2013-01-20 13:33 -0800
                Re: single instance Arne Vajhøj <arne@vajhoej.dk> - 2013-02-24 18:12 -0500
              Re: single instance Arne Vajhøj <arne@vajhoej.dk> - 2013-01-20 21:33 -0500
      Re: single instance "Chris Uppal" <chris.uppal@metagnostic.REMOVE-THIS.org> - 2013-01-06 13:34 +0000
  Re: single instance Daniel Pitts <newsgroup.nospam@virtualinfinity.net> - 2013-01-04 10:26 -0800
    Re: single instance Twirlip of the Mists <twirlip@killfile.me.now.invalid> - 2013-01-04 14:04 -0500
  Re: single instance stledger@lanl.gov - 2013-01-16 14:51 -0800
    Re: single instance stledger@lanl.gov - 2013-01-16 15:09 -0800

csiph-web