我有一个Java servlet,它通过TCP连接调用另一个软件(比如S)。该软件S使用网络资源,并且输出必须从超链接中检索(使用wget)。
由于它是我需要从(无论请求)下载我的结果相同的超链接,它会导致不正确的结果几个请求。我基本上需要在不同进程间锁定这个网络资源的使用(我相信每个来自servlet的调用都会创建一个新进程)。
我试图使用ReentrantLock(但我想它只适用于线程而不是跨进程)。
请让我知道这是如何实现的。用Java锁定进程
谢谢
我有一个Java servlet,它通过TCP连接调用另一个软件(比如S)。该软件S使用网络资源,并且输出必须从超链接中检索(使用wget)。
由于它是我需要从(无论请求)下载我的结果相同的超链接,它会导致不正确的结果几个请求。我基本上需要在不同进程间锁定这个网络资源的使用(我相信每个来自servlet的调用都会创建一个新进程)。
我试图使用ReentrantLock(但我想它只适用于线程而不是跨进程)。
请让我知道这是如何实现的。用Java锁定进程
谢谢
以下是如何在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();
}
});
}
谢谢。这应该适用于我:) – Leo 2012-03-24 22:24:38
只有在获取锁的进程仍处于活动状态时,这才起作用。如果没有,锁似乎隐含释放。换句话说,如果一个进程“死亡”而没有手动释放锁,这似乎不起作用。 – searchengine27 2015-08-24 20:51:40
你为什么重复使用这个TCP连接?如果设置起来很简单,只需在每次需要时设置一个即可。例如,对于HTTP请求,您应该每次都提出一个新请求。
我的猜测是你有static
不应该这样,所以多个线程都应该使用它,当他们都应该有自己的版本。
如果价格昂贵,请考虑使用ThreadLocal创建一个每线程。
如果即使这不起作用,并且您不介意线程阻塞,只需将“synchronized”添加到导致问题的方法即可。
您试图锁定的资源必须支持查找。如果服务不需要被外部锁定,那会更好。
作为解决方案,您可以使用ServerSocket在进程之间锁定资源。
如果他们在同一个容器中运行,并调用到相同的资源,可以考虑使用['synchronized'(http://docs.oracle.com/javase/tutorial/essential/concurrency/syncmeth。 HTML)。请注意,这适用于_threads_。对于进程,如上所示,看看[这里](http://stackoverflow.com/questions/5297813/cross-process-synchronization-in-java)。 – MrGomez 2012-03-22 21:32:21
正常工作的服务器不应该为每个客户端创建一个进程。 – 2012-03-22 21:35:53