简体   繁体   English

Java退出程序而不退出JVM

[英]Java exit a program without quitting JVM

I want to exit a java process and free all the resources before it finishes its normal running, if a certain condition is meet. 如果要满足某个条件,我想退出Java进程并释放所有资源,直到它完成其正常运行。 I dont however want to quit JVM, as I have other java programs running at the same time. 但是,我不想退出JVM,因为我同时运行其他Java程序。 Does return; 确实return; do the above, or is there a better way to do it? 做到以上几点,还是有更好的方法呢?

Thanks. 谢谢。

There is one JVM process per running Java application. 每个运行的Java应用程序都有一个JVM进程。 If you exit that application, the process's JVM gets shut down. 如果退出该应用程序,则进程的JVM将关闭。 However, this does not affect other Java processes. 但是,这不会影响其他Java进程。

You need to understand the JVM mechanism and clarify the terminology. 您需要了解JVM机制并阐明术语。

Let's use the following as datum for the terminology. 让我们将以下内容用作术语的基准。

  • Threads are divisions of concurrently processed flows within a process. 线程是进程中同时处理的流的划分。

  • A process is an OS level thread. 进程是操作系统级别的线程。 The OS manages the processes. 操作系统管理进程。 A process is terminated by sending a termination signal to the OS management. 通过向OS管理发送终止信号来终止进程。 The signal may be sent by the process itself or by another process that has the applicable privilege. 信号可以由进程本身或具有适用特权的另一个进程发送。

  • Within a process, you can create process level threads. 在流程内,您可以创建流程级线程。 Process level threads are normally facilitated by the process management of the OS, but they are initiated by the process and terminated by the process. 进程级别线程通常通过OS的进程管理来促进,但是它们由进程启动,并由进程终止。 Therefore, process level threads are not the same as processes. 因此,进程级线程与进程不同。

  • An application is a collection of systems, programs and/or threads that cooperate in various forms. 应用程序是以各种形式协作的系统,程序和/或线程的集合。 A program or process within an application may terminate without terminating the whole application. 应用程序中的程序或进程可以终止而不会终止整个应用程序。

Within the context of JVM terminology, program may be one of the following. 在JVM术语的上下文中,程序可以是以下之一。

  • A program is run per JVM process. 每个JVM进程都会运行一个程序。 Each program consumes one JVM process and is invoked by supplying the classpath of java bytecode and specifying the main entry point found in the classpath. 每个程序消耗一个JVM进程,并通过提供Java字节码的类路径并指定在类路径中找到的主要入口点来调用。 When you terminate a java program, the whole jvm process that ran that program also terminates. 当您终止Java程序时,运行该程序的整个jvm进程也会终止。

  • A program is run per process level thread. 每个进程级线程都会运行一个程序。 For example, an application run within a tomcat or JEE server is run as a thread within the JEE process. 例如,在tomcat或JEE服务器中运行的应用程序在JEE进程中作为线程运行。 The JEE process is itself a program consuming one JVM process. JEE进程本身就是一个消耗一个JVM进程的程序。 When you terminate an application program, the JEE process does not terminate. 终止应用程序时,JEE进程不会终止。

You may initiate process level threads within a java program. 您可以在Java程序中启动进程级线程。 You may write code that terminates a thread but that would not terminate the process (unless it is the last and only running thread in the process). 您可以编写终止线程但不会终止进程的代码(除非它是进程中的最后一个也是唯一正在运行的线程)。 The JVM garbage collection would take care of freeing of resources and you do not need to free resources yourself after a process level thread is terminated. JVM垃圾回收将负责释放资源,并且在进程级线程终止后,您无需自己释放资源。

The above response is simplified for comprehension. 为简化理解,简化了以上响应。 Please read up on OS design and threading to facilitate a better understanding of processes and the JVM mechanism. 请仔细阅读OS设计和线程,以促进对进程和JVM机制的更好理解。

If the other threads running concurrently are not daemon threads, leaving main will not terminate the VM. 如果同时运行的其他线程不是守护程序线程,则离开main不会终止VM。 The other threads will continue running. 其他线程将继续运行。

I completely missed the point though. 我完全错了。

If you start each program in a separate JVM, calling System.exit() in one of them will not influence the others, they're entirely different processes. 如果在单独的JVM中启动每个程序,则在其中一个中调用System.exit()不会影响其他程序,它们是完全不同的过程。

If you're starting them through a single script or something, depending on how it is written, something else could be killing the other processes. 如果您是通过单个脚本或其他方式启动它们,则取决于其编写方式,那么其他方式可能会杀死其他进程。 Without precise information about how you start these apps, there's really no telling what is going on. 如果没有有关如何启动这些应用程序的准确信息,则实际上是无法告诉发生了什么。

@aix's answer is probably apropos to your question. @aix的答案可能与您的问题有关。 Each time you run the java command (or the equivalent) you get a different JVM instance. 每次您运行java命令(或等效命令)时,都会得到一个不同的JVM实例。 Calling System.exit() in one JVM instance won't cause other JVM instances to exit. 在一个JVM实例中调用System.exit()不会导致其他JVM实例退出。 (Try it and see!) (试试看!)

It is possible to create a framework in which you do run multiple programs within the same JVM. 可以创建一个框架,在其中您可以在同一JVM中运行多个程序。 Indeed this is effectively what you do when you run a "bean shell". 实际上,这实际上是您在运行“ bean shell”时所做的事情。 The same sort of thing happens when your "programs" are services (or webapps, or whatever you call them) running in some application server framework. 当您的“程序”是在某些应用程序服务器框架中运行的服务(或Web应用程序,或您所谓的它们)时,会发生同样的事情。

The bad news is that if you do this kind of thing, there is no entirely reliable way make an individual "program" go away. 坏消息是,如果您做这种事情,没有完全可靠的方法可以使单个“程序”消失。 In particular, if the program is not designed to be cooperative (eg if it doesn't check for interrupts), you will have to resort to the DEPRECATED Thread.stop() method and friends. 特别是,如果程序不是设计为协作的(例如,如果它不检查中断),则必须诉诸DEPRECATED Thread.stop()方法和朋友。 And those methods can have nasty consequences for the JVM and the other programs running in it. 这些方法可能会对JVM和其中运行的其他程序造成不良后果。

In theory, the solution to that problem is to use Isolates. 从理论上讲,解决该问题的方法是使用隔离。 Unfortunately, I don't think that any mainstream JVMs support Isolates. 不幸的是,我不认为任何主流JVM都支持隔离。

Some common usecases leading these kind of requirements can be solved through tools like Nailgun, or Drip. 可以通过Nailgun或Drip之类的工具解决导致此类需求的一些常见用例。

Nailgun allows you to run what appears to be multiple independent executions of a commandline program, but they all happen in the same JVM. Nailgun允许您运行似乎是命令行程序的多个独立执行的程序,但是它们都发生在同一JVM中。 Therefore repeated JVM start-up time does not have to be endured. 因此,不必忍受重复的JVM启动时间。 If these execution interact with global state, then the JVM will get polluted in time and things start to break up. 如果这些执行与全局状态交互,那么JVM将及时受到污染,事情开始崩溃。

Drip will use a new JVM for each execution, but it always keeps a precreated JVM with the correct classpath and options ready. Drip每次执行都会使用一个新的JVM,但是它始终保持预先创建的JVM具有正确的类路径和选项。 This is less performant, but it can guarantee correctness through isolation. 这性能较低,但是可以通过隔离来保证正确性。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM