Блокировка процесса в Java - PullRequest
1 голос
/ 23 марта 2012

У меня есть сервлет Java, который вызывает другое программное обеспечение (скажем, S) по TCP-соединению.Это программное обеспечение S использует сетевой ресурс, и вывод должен быть получен из гиперссылки (с помощью wget).

Поскольку это та же самая гиперссылка, из которой мне нужно загрузить свой результат (независимо от запроса), он приводит кв неправильные результаты несколько запросов.По сути, мне нужно заблокировать использование этого сетевого ресурса в разных процессах (я думаю, что каждый вызов сервлета будет создавать новый процесс).

Я пытался использовать ReentrantLock (но, полагаю, он работает только стемы, а не процессы).

Пожалуйста, дайте мне знать, как этого можно достичь.

Спасибо

Ответы [ 3 ]

2 голосов
/ 23 марта 2012

Вот как сделать межпроцессную блокировку в 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(); 
    } 
}); 
}     
0 голосов
/ 23 марта 2012

Ресурс, который вы пытаетесь заблокировать, должен поддерживать поиск.Было бы лучше, если бы службу не нужно было блокировать извне.

В качестве обходного пути вы можете использовать ServerSocket для блокировки ресурса между процессами.

0 голосов
/ 23 марта 2012

Почему вы повторно используете это TCP-соединение? Если его легко настроить, просто устанавливайте его каждый раз, когда вам это нужно. Например, для HTTP-запроса вы должны просто каждый раз создавать новый запрос.

Я предполагаю, что у вас есть что-то static, которого не должно быть, поэтому несколько потоков используют его, когда все они должны иметь свою собственную версию.

Если они дорогие, рассмотрите возможность создания одного потока на ThreadLocal .

Если даже это не работает, и вы не возражаете против блокировки потоков, просто добавьте «синхронизированный» к методу, вызывающему проблему.

...