Используй скрытый файл как лок: при запуске программы смотришь, если файл есть, закругляемся и выходим, иначе создаем файл и продолжаем. Только есть 2 момента:
1. Если 2 инстанса программы были запущены практически одновременно, оба могут не найти файл и попытаться создать его, поэтому лучше проверять этот случай:
File file = new File("<your_path_here>");
if (!file.createNewFile) {
System.out.pprintln("The instance is already running");
return;
}
2. Использовать try-finally или
shutdown hook, чтобы удалить файл.