原理:
JDK的nio包中FileLock实现类似Linux fcntl的文件锁, 可使文件被进程互斥访问. 借助此功能, 可以实现强大的Java进程互斥锁, 从而在应用层面保证同一时间只有惟一的Jar应用进程在运行! 避免某些因素导致jar重复执行, 多个进程产生竞争,破坏业务数据. (当然, 你可以借助类似ubuntu的upstart脚本或者ps -p <pid>之类的做法来做到相同的功能).
实现:
- package test;
- import java.io.File;
- import java.io.IOException;
- import java.io.RandomAccessFile;
- import java.nio.channels.FileChannel;
- import java.nio.channels.FileLock;
- import java.util.concurrent.Callable;
- import java.util.concurrent.TimeUnit;
- public class FileLockTest {
- public static void main(String[] args) throws Exception {
- exclusiveWithFileLock(new Callable<Void>() {
- @Override
- public Void call() throws Exception {
- TimeUnit.SECONDS.sleep(10); // 使用休眠模拟业务逻辑
- return null;
- }
- });
- }
- public static <V> V exclusiveWithFileLock(Callable<V> caller)
- throws Exception {
- File lockFile = new File(“/tmp/”+FileLockTest.class.getCanonicalName());//使用类名做为文件名称
- if (!lockFile.exists()) {
- if (!lockFile.getParentFile().exists()) {
- lockFile.getParentFile().mkdirs();
- }
- if (!lockFile.createNewFile()) {
- throw new IOException(“create lock file failed! “);
- }
- }
- FileChannel fc = null;
- try {
- fc = new RandomAccessFile(lockFile,”rw”).getChannel();
- FileLock lck = fc.tryLock();
- if (lck == null) {
- System.out.println(“File is lock by another programme”);
- System.exit(1);
- } else {
- System.out.println(“Do your work here…”);
- return caller.call();
- }
- } finally {
- if (fc != null) {
- fc.close();
- }
- }
- return null;
- }
- }
复制代码
结果:
- xuser@pc120:~/myworkspace/source/jademo/src$ java test.FileLockTest
- File is lock by another programme
- xuser@pc120:~/myworkspace/source/jademo/src$ java test.FileLockTest
- Do your work here…
复制代码
优势:
1. 实现简单, 功能强大.