我有一个Java servlet,通过TCP连接调用另一个软件(比方说S)。该软件S使用网络资源,输出必须从超链接中恢复(使用wget)。
由于它是相同的超链接,我需要从(无论请求)下载我的结果,它导致不正确的结果几个请求。我基本上需要在不同的进程中锁定这个网络资源的使用(我相信来自servlet的每个调用都将创建一个新进程)。
我试图使用ReentrantLock(但我想它只适用于线程而不是跨进程)。
请告诉我如何实现这一目标。
由于
答案 0 :(得分:2)
以下是如何在Java中进行跨进程锁定。根据需要进行调整,并根据需要添加错误/异常检查/处理。
// Tester
try {
if (crossProcessLockAcquire(SomeClassInYourApp.class, 3000)) {
// Success - This process now has the lock. (Don't keep it too long.)
}
else {
// Fail (Timeout) - Another process still had the lock after 3 seconds.
}
} finally {
crossProcessLockRelease(); // try/finally is very important.
}
// Acquire - Returns success ( true/false )
private static boolean crossProcessLockAcquire(final Class<?> c, final long waitMS) {
if (fileLock == null && c != null && waitMS > 0) {
try {
long dropDeadTime = System.currentTimeMillis() + waitMS;
File file = new File(lockTempDir, c.getName() + ".lock");
RandomAccessFile randomAccessFile = new RandomAccessFile(file, "rw");
FileChannel fileChannel = randomAccessFile.getChannel();
while (System.currentTimeMillis() < dropDeadTime) {
fileLock = fileChannel.tryLock();
if (fileLock != null) {
break;
}
Thread.sleep(250); // 4 attempts/sec
}
} catch (Exception e) {
e.printStackTrace();
}
}
return fileLock == null ? false : true;
}
// Release
private static void crossProcessLockRelease() {
if (fileLock != null) {
try {
fileLock.release();
fileLock = null;
} catch (IOException e) {
e.printStackTrace();
}
}
}
// Some class vars and a failsafe lock release.
private static File lockTempDir = new File(System.getProperty("java.io.tmpdir") + File.separator + "locks");
private static FileLock fileLock = null;
static {
Runtime.getRuntime().addShutdownHook(new Thread() {
public void run(){
crossProcessLockRelease();
}
});
}
答案 1 :(得分:0)
为什么要重用此TCP连接?如果它易于设置,只需在每次需要时设置一个。例如,对于HTTP请求,您应该每次都发出一个新请求。
我的猜测是你有一些不应该static
的东西,所以当多个线程都应该拥有自己的版本时,它会使用它。
如果费用昂贵,请考虑使用ThreadLocal创建每个帖子一个。
如果即使这样做不起作用,并且您也不介意线程阻塞,只需添加&#34; synchronized&#34;导致问题的方法。
答案 2 :(得分:0)
您尝试锁定的资源必须支持查找。如果服务不需要在外部锁定,那就更好了。
作为一种解决方法,您可以使用ServerSocket在进程之间锁定资源。