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

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

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

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

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

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

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

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

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

 下面就是这次例子的source:

package  multipleStartUp;

interface  MultipleStarted  {

    
public boolean registerPage();
    
    
public void unRegisterPage();
}

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

package  multipleStartUp;

import  java.awt.event.WindowAdapter;
import  java.awt.event.WindowEvent;

import  javax.swing.JFrame;
import  javax.swing.WindowConstants;

public   class  FrameA  extends  JFrame {
    
private static final long serialVersionUID = 1L;
    MultipleStarted multi 
= null;
    FrameA()
{
        
super();
//        multi = new ByListenningToSocket();
//        multi = new ByWriteInfoToFile();
        multi = new ByFileLock();
        initialize();
        
if(!multi.registerPage()){
            System.out.println(
"You have open a same page!");
            System.exit(
0);
        }

    }

    
private void initialize(){
        
this.setSize(200300);
        
this.setTitle("FrameA");
        
this.addWindowListener(new WindowAdapter(){
            
public void windowClosing(WindowEvent e){
                multi.unRegisterPage();
            }

        }
);
    }

    
    
public static void main(String[] args){
        FrameA a  
= new FrameA();
        a.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        a.setVisible(
true);
    }

}

 

package  multipleStartUp;

import  java.io.File;
import  java.io.FileOutputStream;
import  java.nio.channels.FileChannel;
import  java.nio.channels.FileLock;

public   class  ByFileLock  implements  MultipleStarted {
    
private String fileName = "temp";
    
private FileOutputStream fos = null;
    
private FileChannel fChannel = null;
    
    ByFileLock()
{
        
try{
            fos 
= new FileOutputStream(new File(fileName));
            fChannel 
= fos.getChannel();
        }
catch(Exception e){
            System.out.println(
"Error occur while getting fileChannel!");
        }

    }

    @Override
    
public boolean registerPage() {
        
try{
            
if(fChannel != null){
                FileLock fLock 
= fChannel.tryLock();
                
if(fLock != null){
                    
return true;
                }
else{
                    unRegisterPage();
                }

            }

        }
catch(Exception e){    
        }
        
        
return false;
    }


    @Override
    
public void unRegisterPage() {
        
try{
            
if(fChannel != null){
                fChannel.close();
            }

            
if(fos != null){
                fos.close();
            }

        }
catch(Exception e){        
        }
        
    }

}

 

package  multipleStartUp;

import  java.io.File;
import  java.io.FileInputStream;
import  java.io.FileOutputStream;
import  java.io.ObjectInputStream;
import  java.io.ObjectOutputStream;

public   class  ByWriteInfoToFile  implements  MultipleStarted {

    
private String fileName = "temp.serialize";
    @Override
    
public boolean registerPage() {
        
try{
            File file 
= new File(fileName);
            
if(!file.exists()){
                file.createNewFile();    
            }

            
if(isPageStarted(file)){
                
return false;
            }
        
            ObjectOutputStream oos 
= new ObjectOutputStream(new FileOutputStream(file));
            
boolean isOpen = true;
            oos.writeBoolean(isOpen);
            oos.close();
        }
catch(Exception e){
            
return false;
        }

        
return true;
    }


    
private boolean isPageStarted(File file){
        
try{
            ObjectInputStream ois 
= new ObjectInputStream(new FileInputStream(file));
            
boolean isOpen = ois.readBoolean();
            
if(isOpen){
                
return true;
            }

        }
catch(Exception e){
            
return false;
        }

        
return false;
    }

    
    @Override
    
public void unRegisterPage() {
        
try{
            File file 
= new File(fileName);
            
if(!file.exists()){
                file.createNewFile();    
            }
    
            ObjectOutputStream oos 
= new ObjectOutputStream(new FileOutputStream(file));
            
boolean isOpen = false;
            oos.writeBoolean(isOpen);
            oos.flush();
            oos.close();
        }
catch(Exception e){
        }

        
    }


}

 

package  multipleStartUp;

import  java.net.InetAddress;
import  java.net.ServerSocket;

public   class  ByListenningToSocket  implements  MultipleStarted {
    
private int port = 4000;
    
private InetAddress local = null;
    ServerSocket socket 
= null;
    ByListenningToSocket()
{    
    }


    @Override
    
public boolean registerPage() {
        
try {
            local 
= InetAddress.getLocalHost();
            socket 
= new ServerSocket(port,100,local);
        }
 catch (Exception e){
            
//e.printStackTrace();
            return false;
        }

        
return true;
    }


    @Override
    
public void unRegisterPage() {
        
try{
            
if(socket != null){
                socket.close();
            }

        }
catch(Exception e){    
        }
    
    }
    
}

 

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

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

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

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值