Liny_@NotePad

沉迷ACG中

使用文件锁防止多个应用。。

YOYO posted @ 2009年11月11日 07:47 in 【Java SE】 with tags 单实例 文件操作 , 2561 阅读

 原先发的是通过占用固定端口来判断程序是否重复打开,显然很容易和其他应用程序的端口冲突,

在研究Java能不能访问系统内核对象之前。。先用比较简单的方法:对一个文件加锁来防止多个应用重复打开。

这个方法的缺陷是需要另一个文件参与。

首先贴下测试代码:

  1. package org.yoyo.test;
  2.  
  3. import java.awt.Toolkit;
  4. import java.awt.event.WindowAdapter;
  5. import java.awt.event.WindowEvent;
  6.  
  7. import javax.swing.JFrame;
  8. import javax.swing.JLabel;
  9. import javax.swing.JOptionPane;
  10.  
  11. import org.yoyo.lock.IOLock;
  12.  
  13. public class TestIOLock {
  14.  
  15.         /**
  16.          * @param args
  17.          */
  18.         public static void main(String[] args) {
  19.                 if (IOLock.lock()) {
  20.                         new JFrame() {
  21.                                 private static final long serialVersionUID = 1L;
  22.  
  23.                                 {
  24.                                         this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  25.                                         this.setSize(200, 200);
  26.                                         this.setLocation((int) (Toolkit.getDefaultToolkit()
  27.                                                         .getScreenSize().getWidth() - this.getWidth()) / 2,
  28.                                                         (int) (Toolkit.getDefaultToolkit().getScreenSize()
  29.                                                                         .getHeight() - this.getHeight()) / 2);
  30.                                         this.setTitle("程序");
  31.                                         this.add(new JLabel("运行中", JLabel.CENTER));
  32.  
  33.                                         this.addWindowListener(new WindowAdapter() {
  34.  
  35.                                                 @Override
  36.                                                 public void windowClosing(WindowEvent e) {
  37.                                                         IOLock.unlock();
  38.                                                 }
  39.  
  40.                                         });
  41.  
  42.                                         this.setVisible(true);
  43.                                 }
  44.                         };
  45.                 } else {
  46.                         JOptionPane.showMessageDialog(null, "已有相同程序运行!", "错误", JOptionPane.ERROR_MESSAGE);
  47.                 }
  48.         }
  49. }

 下面是一开始写的。。直接读取项目目录下的lock文件(请自己新建),打成jar包后就不能读到了 囧。

  1. package org.yoyo.lock;
  2.  
  3. import java.io.FileNotFoundException;
  4. import java.io.IOException;
  5. import java.io.RandomAccessFile;
  6. import java.nio.channels.FileLock;
  7.  
  8. public class IOLock {
  9.  
  10.         private static final String FILE_NAME = "lock";
  11.  
  12.         private static final String FILE_PATH = IOLock.class.getClassLoader()
  13.                         .getResource(FILE_NAME).getPath();
  14.  
  15.         private static RandomAccessFile file = null;
  16.        
  17.         private static FileLock lock = null;
  18.        
  19.         static {
  20.                 try {
  21.                         file = new RandomAccessFile(FILE_PATH, "rw");
  22.                 } catch (FileNotFoundException e) {
  23.                         e.printStackTrace();
  24.                 }
  25.         }
  26.  
  27.         public synchronized static boolean lock() {
  28.                 try {
  29.                         if (null != lock) {
  30.                                 lock.release();
  31.                         }
  32.                         lock = file.getChannel().tryLock();
  33.                        
  34.                         return lock != null;
  35.                 } catch (IOException e) {
  36.                         e.printStackTrace();
  37.                         return false;
  38.                 }
  39.         }
  40.  
  41.         public synchronized static void unlock() {
  42.                 try {
  43.                         if (null != lock) {
  44.                                 lock.release();
  45.                         }
  46.                 } catch (IOException e) {
  47.                         e.printStackTrace();
  48.                 }
  49.         }
  50.  
  51. }

  如果要打jar包得放到项目外面去,因此接下来的改正是改成偷偷往用户的主目录下放一个文件。。
只需要将上面的两个常量修改一下,FILE_NAME改成比较不会重复的名字,FILE_PATH则引自user.home:

  1.         private static final String FILE_NAME = "org.yoyo.io.lock";
  2.  
  3.         private static final String FILE_PATH = System.getProperty("user.home") + "\\" + FILE_NAME;

这样每次启动时就会在user.home目录下创建FILE_NAME的文件(如果不存在这个文件的话)。
根据这个文件判断是否开启了多个进程。


登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter