天天看点

学习笔记之java中防止多重启动

最近在项目中遇到防止多重启动的问题 ,这也使得我开始关注解决这个问题的方法。下面我就说一下我所知道的解决多重启动的方法。当然,思想都来自网上,我这里就是总结并给出相应的实现。

当然你可能需要在同一个JVM下防止多重启动, 很抱歉,这不是本篇所关注的重点,但是你可以通过单例模式很方便的实现,其他的实现方式,还待你的发现。

本篇仅针对在不同的JVM下防止对同一个画面的多重启动。

防止多重启动,目前我知道有以下3种方法:

1,绑定端口;  2,将启动信息保存到文件;  3,文件加锁

这三种方法也各有缺点,方法1的优点是控制通过编程来实现,没有依赖本地的文件,缺点是必须保证绑定的端口没有被其它应用程序所占用。方法2和方法3都需要依赖于一个本地文件,并且方法2还有一个致命的缺陷:程序在运行过程中断电,程序将再无法启动。比较后我认为,对文件加锁的方法是最可行的方案。

 下面我就对上述的三种解决办法分别给出示例,请先看下图:

学习笔记之java中防止多重启动

从上图中可以看出我们是要防止对FrameA的多重启动。这里用到一个接口MultipleStarted,它的两个方法分别用来注册和注销启动画面的信息。类ByFileLock,ByListenningToSocket,ByWriteInfoToFile分别表示用文件加锁,端口绑定,向文件写信息的方式来实现防止多重启动。

 下面就是这次例子的source:

学习笔记之java中防止多重启动

package  multipleStartUp;

学习笔记之java中防止多重启动
学习笔记之java中防止多重启动
学习笔记之java中防止多重启动

interface  MultipleStarted  ... {

学习笔记之java中防止多重启动
学习笔记之java中防止多重启动

    public boolean registerPage();

学习笔记之java中防止多重启动
学习笔记之java中防止多重启动

    public void unRegisterPage();

学习笔记之java中防止多重启动

}

学习笔记之java中防止多重启动

在FrameA中,你可以通过对multi 变量赋值的修改(注释处)来达到通过不同的方式控制多重启动。

学习笔记之java中防止多重启动

package  multipleStartUp;

学习笔记之java中防止多重启动
学习笔记之java中防止多重启动

import  java.awt.event.WindowAdapter;

学习笔记之java中防止多重启动

import  java.awt.event.WindowEvent;

学习笔记之java中防止多重启动
学习笔记之java中防止多重启动

import  javax.swing.JFrame;

学习笔记之java中防止多重启动

import  javax.swing.WindowConstants;

学习笔记之java中防止多重启动
学习笔记之java中防止多重启动
学习笔记之java中防止多重启动

public   class  FrameA  extends  JFrame ... {

学习笔记之java中防止多重启动

    private static final long serialVersionUID = 1L;

学习笔记之java中防止多重启动

    MultipleStarted multi = null;

学习笔记之java中防止多重启动
学习笔记之java中防止多重启动

    FrameA()...{

学习笔记之java中防止多重启动

        super();

学习笔记之java中防止多重启动

//        multi = new ByListenningToSocket();

学习笔记之java中防止多重启动

//        multi = new ByWriteInfoToFile();

学习笔记之java中防止多重启动

        multi = new ByFileLock();

学习笔记之java中防止多重启动

        initialize();

学习笔记之java中防止多重启动
学习笔记之java中防止多重启动

        if(!multi.registerPage())...{

学习笔记之java中防止多重启动

            System.out.println("You have open a same page!");

学习笔记之java中防止多重启动

            System.exit(0);

学习笔记之java中防止多重启动

        }

学习笔记之java中防止多重启动

    }

学习笔记之java中防止多重启动
学习笔记之java中防止多重启动

    private void initialize()...{

学习笔记之java中防止多重启动

        this.setSize(200, 300);

学习笔记之java中防止多重启动

        this.setTitle("FrameA");

学习笔记之java中防止多重启动
学习笔记之java中防止多重启动

        this.addWindowListener(new WindowAdapter()...{

学习笔记之java中防止多重启动
学习笔记之java中防止多重启动

            public void windowClosing(WindowEvent e)...{

学习笔记之java中防止多重启动

                multi.unRegisterPage();

学习笔记之java中防止多重启动

            }

学习笔记之java中防止多重启动

        });

学习笔记之java中防止多重启动

    }

学习笔记之java中防止多重启动
学习笔记之java中防止多重启动
学习笔记之java中防止多重启动

    public static void main(String[] args)...{

学习笔记之java中防止多重启动

        FrameA a  = new FrameA();

学习笔记之java中防止多重启动

        a.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);

学习笔记之java中防止多重启动

        a.setVisible(true);

学习笔记之java中防止多重启动

    }

学习笔记之java中防止多重启动

}

学习笔记之java中防止多重启动

package  multipleStartUp;

学习笔记之java中防止多重启动
学习笔记之java中防止多重启动

import  java.io.File;

学习笔记之java中防止多重启动

import  java.io.FileOutputStream;

学习笔记之java中防止多重启动

import  java.nio.channels.FileChannel;

学习笔记之java中防止多重启动

import  java.nio.channels.FileLock;

学习笔记之java中防止多重启动
学习笔记之java中防止多重启动
学习笔记之java中防止多重启动

public   class  ByFileLock  implements  MultipleStarted ... {

学习笔记之java中防止多重启动

    private String fileName = "temp";

学习笔记之java中防止多重启动

    private FileOutputStream fos = null;

学习笔记之java中防止多重启动

    private FileChannel fChannel = null;

学习笔记之java中防止多重启动
学习笔记之java中防止多重启动
学习笔记之java中防止多重启动

    ByFileLock()...{

学习笔记之java中防止多重启动
学习笔记之java中防止多重启动

        try...{

学习笔记之java中防止多重启动

            fos = new FileOutputStream(new File(fileName));

学习笔记之java中防止多重启动

            fChannel = fos.getChannel();

学习笔记之java中防止多重启动
学习笔记之java中防止多重启动

        }catch(Exception e)...{

学习笔记之java中防止多重启动

            System.out.println("Error occur while getting fileChannel!");

学习笔记之java中防止多重启动

        }

学习笔记之java中防止多重启动

    }

学习笔记之java中防止多重启动

    @Override

学习笔记之java中防止多重启动
学习笔记之java中防止多重启动

    public boolean registerPage() ...{

学习笔记之java中防止多重启动
学习笔记之java中防止多重启动

        try...{

学习笔记之java中防止多重启动
学习笔记之java中防止多重启动

            if(fChannel != null)...{

学习笔记之java中防止多重启动

                FileLock fLock = fChannel.tryLock();

学习笔记之java中防止多重启动
学习笔记之java中防止多重启动

                if(fLock != null)...{

学习笔记之java中防止多重启动

                    return true;

学习笔记之java中防止多重启动
学习笔记之java中防止多重启动

                }else...{

学习笔记之java中防止多重启动

                    unRegisterPage();

学习笔记之java中防止多重启动

                }

学习笔记之java中防止多重启动

            }

学习笔记之java中防止多重启动
学习笔记之java中防止多重启动

        }catch(Exception e)...{    

学习笔记之java中防止多重启动

        }        

学习笔记之java中防止多重启动

        return false;

学习笔记之java中防止多重启动

    }

学习笔记之java中防止多重启动
学习笔记之java中防止多重启动

    @Override

学习笔记之java中防止多重启动
学习笔记之java中防止多重启动

    public void unRegisterPage() ...{

学习笔记之java中防止多重启动
学习笔记之java中防止多重启动

        try...{

学习笔记之java中防止多重启动
学习笔记之java中防止多重启动

            if(fChannel != null)...{

学习笔记之java中防止多重启动

                fChannel.close();

学习笔记之java中防止多重启动

            }

学习笔记之java中防止多重启动
学习笔记之java中防止多重启动

            if(fos != null)...{

学习笔记之java中防止多重启动

                fos.close();

学习笔记之java中防止多重启动

            }

学习笔记之java中防止多重启动
学习笔记之java中防止多重启动

        }catch(Exception e)...{        

学习笔记之java中防止多重启动

        }        

学习笔记之java中防止多重启动

    }

学习笔记之java中防止多重启动

}

学习笔记之java中防止多重启动
学习笔记之java中防止多重启动

package  multipleStartUp;

学习笔记之java中防止多重启动
学习笔记之java中防止多重启动

import  java.io.File;

学习笔记之java中防止多重启动

import  java.io.FileInputStream;

学习笔记之java中防止多重启动

import  java.io.FileOutputStream;

学习笔记之java中防止多重启动

import  java.io.ObjectInputStream;

学习笔记之java中防止多重启动

import  java.io.ObjectOutputStream;

学习笔记之java中防止多重启动
学习笔记之java中防止多重启动
学习笔记之java中防止多重启动

public   class  ByWriteInfoToFile  implements  MultipleStarted ... {

学习笔记之java中防止多重启动
学习笔记之java中防止多重启动

    private String fileName = "temp.serialize";

学习笔记之java中防止多重启动

    @Override

学习笔记之java中防止多重启动
学习笔记之java中防止多重启动

    public boolean registerPage() ...{

学习笔记之java中防止多重启动
学习笔记之java中防止多重启动

        try...{

学习笔记之java中防止多重启动

            File file = new File(fileName);

学习笔记之java中防止多重启动
学习笔记之java中防止多重启动

            if(!file.exists())...{

学习笔记之java中防止多重启动

                file.createNewFile();    

学习笔记之java中防止多重启动

            }

学习笔记之java中防止多重启动
学习笔记之java中防止多重启动

            if(isPageStarted(file))...{

学习笔记之java中防止多重启动

                return false;

学习笔记之java中防止多重启动

            }        

学习笔记之java中防止多重启动

            ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(file));

学习笔记之java中防止多重启动

            boolean isOpen = true;

学习笔记之java中防止多重启动

            oos.writeBoolean(isOpen);

学习笔记之java中防止多重启动

            oos.close();

学习笔记之java中防止多重启动
学习笔记之java中防止多重启动

        }catch(Exception e)...{

学习笔记之java中防止多重启动

            return false;

学习笔记之java中防止多重启动

        }

学习笔记之java中防止多重启动

        return true;

学习笔记之java中防止多重启动

    }

学习笔记之java中防止多重启动
学习笔记之java中防止多重启动
学习笔记之java中防止多重启动

    private boolean isPageStarted(File file)...{

学习笔记之java中防止多重启动
学习笔记之java中防止多重启动

        try...{

学习笔记之java中防止多重启动

            ObjectInputStream ois = new ObjectInputStream(new FileInputStream(file));

学习笔记之java中防止多重启动

            boolean isOpen = ois.readBoolean();

学习笔记之java中防止多重启动
学习笔记之java中防止多重启动

            if(isOpen)...{

学习笔记之java中防止多重启动

                return true;

学习笔记之java中防止多重启动

            }

学习笔记之java中防止多重启动
学习笔记之java中防止多重启动

        }catch(Exception e)...{

学习笔记之java中防止多重启动

            return false;

学习笔记之java中防止多重启动

        }

学习笔记之java中防止多重启动

        return false;

学习笔记之java中防止多重启动

    }

学习笔记之java中防止多重启动
学习笔记之java中防止多重启动

    @Override

学习笔记之java中防止多重启动
学习笔记之java中防止多重启动

    public void unRegisterPage() ...{

学习笔记之java中防止多重启动
学习笔记之java中防止多重启动

        try...{

学习笔记之java中防止多重启动

            File file = new File(fileName);

学习笔记之java中防止多重启动
学习笔记之java中防止多重启动

            if(!file.exists())...{

学习笔记之java中防止多重启动

                file.createNewFile();    

学习笔记之java中防止多重启动

            }    

学习笔记之java中防止多重启动

            ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(file));

学习笔记之java中防止多重启动

            boolean isOpen = false;

学习笔记之java中防止多重启动

            oos.writeBoolean(isOpen);

学习笔记之java中防止多重启动

            oos.flush();

学习笔记之java中防止多重启动

            oos.close();

学习笔记之java中防止多重启动
学习笔记之java中防止多重启动

        }catch(Exception e)...{

学习笔记之java中防止多重启动

        }

学习笔记之java中防止多重启动
学习笔记之java中防止多重启动

    }

学习笔记之java中防止多重启动
学习笔记之java中防止多重启动

}

学习笔记之java中防止多重启动
学习笔记之java中防止多重启动

package  multipleStartUp;

学习笔记之java中防止多重启动
学习笔记之java中防止多重启动

import  java.net.InetAddress;

学习笔记之java中防止多重启动

import  java.net.ServerSocket;

学习笔记之java中防止多重启动
学习笔记之java中防止多重启动
学习笔记之java中防止多重启动

public   class  ByListenningToSocket  implements  MultipleStarted ... {

学习笔记之java中防止多重启动

    private int port = 4000;

学习笔记之java中防止多重启动

    private InetAddress local = null;

学习笔记之java中防止多重启动

    ServerSocket socket = null;

学习笔记之java中防止多重启动
学习笔记之java中防止多重启动

    ByListenningToSocket()...{    

学习笔记之java中防止多重启动

    }

学习笔记之java中防止多重启动
学习笔记之java中防止多重启动

    @Override

学习笔记之java中防止多重启动
学习笔记之java中防止多重启动

    public boolean registerPage() ...{

学习笔记之java中防止多重启动
学习笔记之java中防止多重启动

        try ...{

学习笔记之java中防止多重启动

            local = InetAddress.getLocalHost();

学习笔记之java中防止多重启动

            socket = new ServerSocket(port,100,local);

学习笔记之java中防止多重启动
学习笔记之java中防止多重启动

        } catch (Exception e)...{

学习笔记之java中防止多重启动

            //e.printStackTrace();

学习笔记之java中防止多重启动

            return false;

学习笔记之java中防止多重启动

        }

学习笔记之java中防止多重启动

        return true;

学习笔记之java中防止多重启动

    }

学习笔记之java中防止多重启动
学习笔记之java中防止多重启动

    @Override

学习笔记之java中防止多重启动
学习笔记之java中防止多重启动

    public void unRegisterPage() ...{

学习笔记之java中防止多重启动
学习笔记之java中防止多重启动

        try...{

学习笔记之java中防止多重启动
学习笔记之java中防止多重启动

            if(socket != null)...{

学习笔记之java中防止多重启动

                socket.close();

学习笔记之java中防止多重启动

            }

学习笔记之java中防止多重启动
学习笔记之java中防止多重启动

        }catch(Exception e)...{    

学习笔记之java中防止多重启动

        }    

学习笔记之java中防止多重启动

    }    

学习笔记之java中防止多重启动

}

学习笔记之java中防止多重启动

 当然,这些仅仅是说明性的示范,告诉我们可以通过这种方法解决问题,至于实现中的细节问题,根据不同的情况,必定不同。

这也仅仅是防止多重启动多种方法中的3种而已,必定还有很多我不知道的解决方法,期待中......

说明:由于是示范性例子,上述source中没有对异常作统一的出理,并且source中可能还有很多的不足,如有发现,还望指出。