我有一個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