Если я верю этому статья :
наличие первой инстанции пытаются открыть сокет слушания в интерфейсе localhost. Если это в состоянии открыть сокет, предполагается, что это - первая инстанция приложения, которое будет запущено. В противном случае предположение - то, что экземпляр этого приложения уже работает. Новый экземпляр должен уведомить существующий экземпляр, что запуск был предпринят, затем выйдите. Существующий экземпляр вступает во владение после получения уведомления и запускает событие в слушателя, который обрабатывает действие.
Примечание: Ахе упоминает в комментарии, что использование InetAddress.getLocalHost()
может быть хитрым:
- это не работает как ожидалось в среде DHCP, потому что возвращенный адрес зависит от того, имеет ли компьютер доступ к сети.
Решение состояло в том, чтобы открыть соединение с [1 134]InetAddress.getByAddress(new byte[] {127, 0, 0, 1})
;
, Вероятно, связанный с [1 113] ошибка 4435662 .
getLocalHost
: возвратите IP-адрес машины, по сравнению с Фактическими результатами: возвратитесь 127.0.0.1
. <час>удивительно иметь
getLocalHost
возврат127.0.0.1
на Linux, но не на окнах.
Или можно использовать ManagementFactory
объект. Как объяснено здесь :
getMonitoredVMs(int processPid)
метод получает как параметр текущий PID приложения, и поймайте имя приложения, которое называют из командной строки, например, приложение было запущено отc:\java\app\test.jar
путь, тогда переменная значения"c:\\java\\app\\test.jar
". Таким образом, мы поймаем просто имя приложения на строке 17 из кода ниже.
После этого, мы ищем JVM другой процесс с тем же именем, если мы нашли его, и PID приложения отличается, это означает, что это - второй экземпляр приложения.
JNLP предлагает также SingleInstanceListener
Можно открыть Memory Mapped File и затем видеть, открыт ли тот файл уже. если это уже открыто, можно возвратиться из основного.
Другие пути должен использовать файлы блокировки (стандартная практика Unix). Еще один путь состоит в том, чтобы поместить что-то в буфер обмена, когда основные запуски после проверки, если что-то уже находится в буфере обмена.
Еще, можно открыть сокет в режиме прослушивания (ServerSocket). Сначала попытайтесь соединиться с сокетом hte; если Вы не можете соединиться, затем открыть serversocket., если Вы соединяетесь, то Вы знаете, что другой экземпляр уже работает.
Так, в значительной степени любой системный ресурс может использоваться для знания, что приложение работает.
BR, ~A
Вы могли попытаться использовать Предпочтительный API. Это независимо от платформы.
Класс ManagementFactory поддерживал в J2SE 5.0 или позже деталь
, но теперь я использую J2SE 1.4, и я нашел этот http://audiprimadhanty.wordpress.com/2008/06/30/ensuring-one-instance-of-application-running-at-one-time/ , но я никогда не тестирую. Что Вы думаете об этом?
Мы используем захват файла для этого (захватите монопольную блокировку на волшебном файле в каталоге данных приложения пользователя), но мы, прежде всего, интересуемся предотвращением нескольких экземпляров от когда-либо выполнения.
, При попытке иметь второй экземпляр, передают командную строку args, и т.д.... к первой инстанции, затем использование сокетного соединения на localhost будет уничтожать двух птиц с одним камнем. Общий алгоритм:
В Windows можно использовать launch4j.
Я записал библиотеку Java по имени Unique4j для этой самой цели. Вы видите его в https://github.com/prat-man/unique4j. Библиотека доступна на Знатоке, Центральном также для легкого доступа и интеграции.
Это межплатформенное совместимый и поддерживает Java 1.6 +. Библиотеке лицензируют под Apache 2.0, который делает ее идеалом для использования с любым проектом и открыто полученный и закрытый исходный код.
Это использует комбинацию блокировок файла и блокировок динамического порта, чтобы обнаружить и связаться между экземплярами с основной целью разрешения только одного экземпляра работать.
следующее является простым примером использования и возможностями Unique4j. Библиотека обеспечивает больше настроек и функций, которые могут быть переопределены для большего количества функций и возможностей.
import tk.pratanumandal.unique4j.Unique;
import tk.pratanumandal.unique4j.exception.Unique4jException;
public class Unique4jDemo {
// unique application ID
public static String APP_ID = "tk.pratanumandal.unique4j-mlsdvo-20191511-#j.6";
public static void main(String[] args) throws Unique4jException {
// create unique instance
Unique unique = new Unique(APP_ID) {
@Override
public void receiveMessage(String message) {
// display received message from subsequent instance
System.out.println(message);
}
@Override
public String sendMessage() {
// send message to first instance
return "Hello World!";
}
};
// try to obtain lock
boolean lockFlag = unique.acquireLock();
// perform long running tasks here
...
// try to free the lock before exiting program
boolean lockFreeFlag = unique.freeLock();
}
}
я создал его для одного из моих собственных проектов и затем выпустил его как библиотека. Надеюсь, что кто-то находит это полезным.
I have found a solution, a bit cartoonish explanation, but still works in most cases. It uses the plain old lock file creating stuff, but in a quite different view:
http://javalandscape.blogspot.com/2008/07/single-instance-from-your-application.html
I think it will be a help to those with a strict firewall setting.
Я использовал для этого сокеты, и в зависимости от того, находится ли приложение на стороне клиента или на стороне сервера, поведение немного отличается:
В основном методе я использую следующий метод. Это самый простой, самый робастный и наименее навязчивый метод, который я видел, поэтому я решил поделиться им.
private static boolean lockInstance(final String lockFile) {
try {
final File file = new File(lockFile);
final RandomAccessFile randomAccessFile = new RandomAccessFile(file, "rw");
final FileLock fileLock = randomAccessFile.getChannel().tryLock();
if (fileLock != null) {
Runtime.getRuntime().addShutdownHook(new Thread() {
public void run() {
try {
fileLock.release();
randomAccessFile.close();
file.delete();
} catch (Exception e) {
log.error("Unable to remove lock file: " + lockFile, e);
}
}
});
return true;
}
} catch (Exception e) {
log.error("Unable to create and/or lock file: " + lockFile, e);
}
return false;
}