用Java锁定进程

时间:2012-03-22 21:30:51

标签: java process locking

我有一个Java servlet,通过TCP连接调用另一个软件(比方说S)。该软件S使用网络资源,输出必须从超链接中恢复(使用wget)。

由于它是相同的超链接,我需要从(无论请求)下载我的结果,它导致不正确的结果几个请求。我基本上需要在不同的进程中锁定这个网络资源的使用(我相信来自servlet的每个调用都将创建一个新进程)。

我试图使用ReentrantLock(但我想它只适用于线程而不是跨进程)。

请告诉我如何实现这一目标。

由于

3 个答案:

答案 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在进程之间锁定资源。