У меня есть jav-файл java, который я выполняю из командной строки Windows. Код завершается нормально (то есть делает то, что должен), но процесс Java продолжает работать. Приложение однопоточное. Мне нужно нажать Ctrl-c, чтобы остановить процесс после завершения кода, чтобы вернуть командную строку.
Я предполагаю, что мог бы поставить System.exit(0)
в конце моего основного метода, который предположительно исправит это, но у меня сложилось впечатление, что в этом нет необходимости. При каких условиях Java-процессы остаются живыми в конце выполнения? Вот оболочка моего основного метода:
public static void main(String[] args) {
try {
//application code here
Logger.log("Now finished");
} catch (SomeExceptoin e) {
Logger.error("Some error occured");
}
}
Где регистратор - мой собственный невероятно простой статический класс, который просто сбрасывает сообщения в System.out.println()
. «Теперь закончено» отображается в консоли, но процесс продолжает выполняться. Есть идеи?
РЕДАКТИРОВАТЬ: В соответствии с просьбой, вот код регистратора во всей своей красе (я вас предупреждал:)
public class Logger {
public static void logInfo(String logMessage)
{
System.out.println(timestamp() + logMessage);
}
private static String timestamp()
{
SimpleDateFormat formatter = new SimpleDateFormat("yyyy.MM.dd hh:mm:ss");
String timestamp = "[" + formatter.format(new Date()) + "] ";
return timestamp;
}
}
РЕДАКТИРОВАТЬ РЕДАКТИРОВАТЬ: я поставил блок finally на мою попытку выше с кодом дампа потока по ссылке в ответе instanceofTom. Вот вывод:
...
[2010.11.18 11:22:57] Вывод завершен. Вся обработка сейчас завершена.
Название темы: Ссылочный обработчик
java.lang.Object.wait (собственный метод)
java.lang.Object.wait (Object.java:485)
java.lang.ref.Reference $ ReferenceHandler.run (Reference.java:116)
Название темы: Финализатор
java.lang.Object.wait (собственный метод)
java.lang.ref.ReferenceQueue.remove (ReferenceQueue.java:116)
java.lang.ref.ReferenceQueue.remove (ReferenceQueue.java:132)
java.lang.ref.Finalizer $ FinalizerThread.run (Finalizer.java:159)
Название темы: Диспетчер сигналов
Название темы: Attach Listener
Имя темы: Java2D Disposer
java.lang.Object.wait (собственный метод)
java.lang.ref.ReferenceQueue.remove (ReferenceQueue.java:116)
java.lang.ref.ReferenceQueue.remove (ReferenceQueue.java:132)
sun.java2d.Disposer.run (Disposer.java:125)
java.lang.Thread.run (Thread.java:619)
Название темы: главная
java.lang.Thread.getStackTrace (Thread.java:1436)
com.my.code.WorkloadManager.visit (WorkloadManager.java:124)
com.my.code.WorkloadManager.visit (WorkloadManager.java:138)
com.my.code.WorkloadManager.main (WorkloadManager.java:71)
sun.reflect.NativeMethodAccessorImpl.invoke0 (собственный метод)
sun.reflect.NativeMethodAccessorImpl.invoke (NativeMethodAccessorImpl.java:39)
sun.reflect.DelegatingMethodAccessorImpl.invoke (DelegatingMethodAccessorImpl.java:25)
java.lang.reflect.Method.invoke (Method.java:597)
org.eclipse.jdt.internal.jarinjarloader.JarRsrcLoader.main (JarRsrcLoader.java:56)
Название темы: com.google.inject.internal.Finalizer
java.lang.Object.wait (собственный метод)
java.lang.ref.ReferenceQueue.remove (ReferenceQueue.java:116)
java.lang.ref.ReferenceQueue.remove (ReferenceQueue.java:132)
com.google.inject.internal.Finalizer.run (Finalizer.java:114)
Название темы: AWT-Windows
sun.awt.windows.WToolkit.eventLoop (собственный метод)
sun.awt.windows.WToolkit.run (WToolkit.java:291)
java.lang.Thread.run (Thread.java:619)
Имя потока: EventQueueMonitor-ComponentEvtDispatch
java.lang.Object.wait (собственный метод)
java.lang.Object.wait (Object.java:485)
com.sun.java.accessibility.util.ComponentEvtDispatchThread.run (EventQueueMonitor.java:616) ********* *******
Название темы: Ссылочный обработчик
java.lang.Object.wait (собственный метод)
java.lang.Object.wait (Object.java:485)
java.lang.ref.Reference $ ReferenceHandler.run (Reference.java:116)
Название темы: Финализатор
java.lang.Object.wait (собственный метод)
java.lang.ref.ReferenceQueue.remove (ReferenceQueue.java:116)
java.lang.ref.ReferenceQueue.remove (ReferenceQueue.java:132)
java.lang.ref.Finalizer $ FinalizerThread.run (Finalizer.java:159)
Название темы: Диспетчер сигналов
Название темы: Attach Listener
Название темы: Java2D Disposer
java.lang.Object.wait (собственный метод)
java.lang.ref.ReferenceQueue.remove (ReferenceQueue.java:116)
java.lang.ref.ReferenceQueue.remove (ReferenceQueue.java:132)
sun.java2d.Disposer.run (Disposer.java:125)
java.lang.Thread.run (Thread.java:619)
Название темы: главная
java.lang.Thread.getStackTrace (Thread.java:1436)
com.my.code.WorkloadManager.visit (WorkloadManager.java:124)
com.my.code.WorkloadManager.visit (WorkloadManager.java:138)
com.my.code.WorkloadManager.main (WorkloadManager.java:71)
sun.reflect.NativeMethodAccessorImpl.invoke0 (собственный метод)
sun.reflect.NativeMethodAccessorImpl.invoke (NativeMethodAccessorImpl.java:39)
sun.reflect.DelegatingMethodAccessorImpl.invoke (DelegatingMethodAccessorImpl.java:25)
java.lang.reflect.Method.invoke (Method.java:597)
org.eclipse.jdt.internal.jarinjarloader.JarRsrcLoader.main (JarRsrcLoader.java:56)
Название темы: com.google.inject.internal.Finalizer
java.lang.Object.wait (собственный метод)
java.lang.ref.ReferenceQueue.remove (ReferenceQueue.java:116)
java.lang.ref.ReferenceQueue.remove (ReferenceQueue.java:132)
com.google.inject.internal.Finalizer.run (Finalizer.java:114)
Название темы: AWT-Windows
sun.awt.windows.WToolkit.eventLoop (собственный метод)
sun.awt.windows.WToolkit.run (WToolkit.java:291)
java.lang.Thread.run (Thread.java:619)
Имя потока: EventQueueMonitor-ComponentEvtDispatch
java.lang.Object.wait (собственный метод)
java.lang.Object.wait (Object.java:485)
com.sun.java.accessibility.util.ComponentEvtDispatchThread.run (EventQueueMonitor.java:616)