Это не проблема Java. Если вы хотите, чтобы приложение работало в одиночку, без копий, вы должны использовать сценарий оболочки или java-приложение, чтобы создать и снять блокировку где-нибудь.
Вы на самом деле запускаете несколько java, запуская более 1 пакетного задания с помощью одной и той же команды. Windows или Java могут теперь это не то, что вы хотите. Вы можете решить это следующим образом:
public static void main(String [ ] args)
{
createLockIfNotExists();
try {
yourstuff;
} finally {
releaseLock();
}
}
private static void createLockIfNotExists() throws MyLockAlreadyExists {
// A bit tricky
// check if LOCKFILE exists, if yes throw MyLockAlreadyExists
// try to create LOCKFILE, can fail if at 1 ms earlier an other app created
// that file, so an exception while creating also results in LockAlreadyExists
}
Есть ли где-нибудь хорошие примеры, которые обрабатывают эту блокировку? Может быть, в Apache Commons?
Здесь кажется работающим примером для Windows.
Вы также можете использовать базу данных для записи вашей блокировки. Конечно, заблокируйте таблицу блокировок перед ее использованием, чтобы никакие 2 процесса не записали свою блокировку одновременно, а затем прочитали запись блокировки, чтобы проверить, действительно ли вы получили блокировку. Что-то вроде псевдокода:
SELECT * FROM lock_table;
if locks.length > 0: someone else is running
LOCK lock_table;
INSERT INTO lock_table VALUES(my_pid);
UNLOCK lock_table;
SELECT pid FROM lock_table;
if pids.length > 1: what happened?
if pids[0] != my_pid: someone else got the lock
Чуть больше сока, и вы также добавляете не только PID, но и временную метку и проверяете, устарела ли эта временная метка (слишком старая).