lucene代码分析7
程序员文章站
2022-07-09 21:46:31
...
有关 SimpleFSLock 进行 JVM 之间的同步
有时候,我们写 java 程序的时候,也需要不同的 JVM 之间进行同步,来保护一个整个系统中唯一的资源。
如果唯一的资源仅仅在一个进程中,则可以使用线程同步的机制,然而如果唯一的资源要被多个进程进行访问,则需要进程间同步的机制,无论是
Windows 和 Linux 在操作系统层面都有很多的进程间同步的机制。
但进程间的同步却不是 Java 的特长,Lucene 的 SimpleFSLock 给我们提供了一种方式。 如下:
Lock 的抽象类
public abstract class Lock {
public static long LOCK_POLL_INTERVAL = 1000;
public static final long LOCK_OBTAIN_WAIT_FOREVER = -1;
public abstract boolean obtain() throws IOException;
public boolean obtain(long lockWaitTimeout) throws LockObtainFailedException, IOException {
boolean locked = obtain();
if (lockWaitTimeout < 0 && lockWaitTimeout != LOCK_OBTAIN_WAIT_FOREVER)
throw new IllegalArgumentException("...");
long maxSleepCount = lockWaitTimeout / LOCK_POLL_INTERVAL;
long sleepCount = 0;
while (!locked) {
if (lockWaitTimeout != LOCK_OBTAIN_WAIT_FOREVER && sleepCount++ >= maxSleepCount) {
throw new LockObtainFailedException("Lock obtain timed out.");
}
try {
Thread.sleep(LOCK_POLL_INTERVAL);
} catch (InterruptedException ie) {
throw new ThreadInterruptedException(ie);
}
locked = obtain();
}
return locked;
}
public abstract void release() throws IOException;
public abstract boolean isLocked() throws IOException;
}
LockFactory 的抽象类
public abstract class LockFactory {
public abstract Lock makeLock(String lockName);
abstract public void clearLock(String lockName) throws IOException;
}
SimpleFSLock 的实现类
class SimpleFSLock extends Lock {
File lockFile;
File lockDir;
public SimpleFSLock(File lockDir, String lockFileName) {
this.lockDir = lockDir;
lockFile = new File(lockDir, lockFileName);
}
@Override
public boolean obtain() throws IOException {
if (!lockDir.exists()) {
if (!lockDir.mkdirs())
throw new IOException("Cannot create directory: " + lockDir.getAbsolutePath());
} else if (!lockDir.isDirectory()) {
throw new IOException("Found regular file where directory expected: " +
lockDir.getAbsolutePath());
}
return lockFile.createNewFile();
}
@Override
public void release() throws LockReleaseFailedException {
if (lockFile.exists() && !lockFile.delete())
throw new LockReleaseFailedException("failed to delete " + lockFile);
}
@Override
public boolean isLocked() {
return lockFile.exists();
}
}
SimpleFSLockFactory 的实现类
public class SimpleFSLockFactory extends FSLockFactory {
public SimpleFSLockFactory(String lockDirName) throws IOException {
setLockDir(new File(lockDirName));
}
@Override
public Lock makeLock(String lockName) {
if (lockPrefix != null) {
lockName = lockPrefix + "-" + lockName;
}
return new SimpleFSLock(lockDir, lockName);
}
@Override
public void clearLock(String lockName) throws IOException {
if (lockDir.exists()) {
if (lockPrefix != null) {
lockName = lockPrefix + "-" + lockName;
}
File lockFile = new File(lockDir, lockName);
if (lockFile.exists() && !lockFile.delete()) {
throw new IOException("Cannot delete " + lockFile);
}
}
}
};