天天看點

學習筆記之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中可能還有很多的不足,如有發現,還望指出。