Java线程中的System.exit

Java线程中的System.exit,java,multithreading,Java,Multithreading,我的主线程创建了一个新线程 当新线程调用System.exit(-1)时,我的主线程将被关闭。 如何处理退出代码并使主线程保持活动状态 附言。 新线程将调用其他.jar文件中的某些方法,因此我无法修改它。您不能 终止当前运行的Java虚拟机。参数用作状态代码;按照惯例,非零状态代码表示异常终止。 那是javadoc 因此,该方法将终止整个JVM。不仅仅是线程…您的问题非常不清楚,但是如果System.exit调用成功,操作系统将终止您的应用程序 如果您不希望System.exit成功,可以安装安

我的主线程创建了一个新线程 当新线程调用
System.exit(-1)
时,我的主线程将被关闭。 如何处理退出代码并使主线程保持活动状态

附言。 新线程将调用其他
.jar
文件中的某些方法,因此我无法修改它。

您不能

终止当前运行的Java虚拟机。参数用作状态代码;按照惯例,非零状态代码表示异常终止。

那是javadoc


因此,该方法将终止整个JVM。不仅仅是线程…

您的问题非常不清楚,但是如果System.exit调用成功,操作系统将终止您的应用程序

如果您不希望System.exit成功,可以安装安全管理器并阻止它。除此之外,您还可以通过自定义类加载器插入代码并删除调用

编辑:如果您使用安全管理器,抛出SecurityException很可能会终止线程。如果它没有-欺骗和抛出一个线程死亡。如果仍然不行-只需按住线程,例如(;;)线程的
。睡眠(10000)后者将泄漏线程及其资源,但至少不会杀死您的应用程序


使用Java SecurityManager从exit保存主线程,并使用SecurityManager运行其他线程代码

编辑:
从Tomcat或其他服务器上了解如何在JSP中使用类似于
的代码

班级:

public class MySecurityManager extends SecurityManager {
    @Override
    public void checkPermission(Permission perm) {
    }

    @Override
    public void checkPermission(Permission perm, Object context) {
    }

    @Override
    public void checkCreateClassLoader() {
    }

    @Override
    public void checkAccess(Thread t) {
    }

    @Override
    public void checkAccess(ThreadGroup g) {
    }

    @Override
    public void checkExit(int status) {
        throw new SecurityException("not allow to call System.exit");
    }

    @Override
    public void checkExec(String cmd) {
    }

    @Override
    public void checkLink(String lib) {
    }

    @Override
    public void checkRead(FileDescriptor fd) {
    }

    @Override
    public void checkRead(String file) {
    }

    @Override
    public void checkRead(String file, Object context) {
    }

    @Override
    public void checkWrite(FileDescriptor fd) {
    }

    @Override
    public void checkWrite(String file) {
    }

    @Override
    public void checkDelete(String file) {
    }

    @Override
    public void checkConnect(String host, int port) {
    }

    @Override
    public void checkConnect(String host, int port, Object context) {
    }

    @Override
    public void checkListen(int port) {
    }

    @Override
    public void checkAccept(String host, int port) {
    }

    @Override
    public void checkMulticast(InetAddress maddr) {
    }

    @Override
    public void checkPropertiesAccess() {
    }

    @Override
    public void checkPropertyAccess(String key) {
    }

    @Override
    public boolean checkTopLevelWindow(Object window) {
        return super.checkTopLevelWindow(window);
    }

    @Override
    public void checkPrintJobAccess() {
    }

    @Override
    public void checkSystemClipboardAccess() {
    }

    @Override
    public void checkAwtEventQueueAccess() {
    }

    @Override
    public void checkPackageAccess(String pkg) {
    }

    @Override
    public void checkPackageDefinition(String pkg) {
    }

    @Override
    public void checkSetFactory() {
    }

    @Override
    public void checkMemberAccess(Class<?> clazz, int which) {
    }

    @Override
    public void checkSecurityAccess(String target) {
    }
}
System.setSecurityManager(new MySecurityManager());

这种方法对中断有反应吗?你有办法让它退出吗?呃,JVM的终止不就意味着一切的结束吗?不管中断如何?@Thihara问题似乎是:如何在不停止主线程的情况下停止该线程。当然,System.exit将终止JVM,OP似乎理解这一点。但实际上我可以看到它也可以理解为:新线程确实调用System.exit,我想阻止它这样做。这是不清楚的…我会说,使用
return
代替
System.exit(-1)
,但是你说你不能修改代码。不那么容易@xagyg,
return
通常是一个错误的选择,因为您不知道代码可能在哪里继续,您需要一些异常/错误(例如ThreadDeath)。然而字节码插装并没有那么难,我可能会这么做。最后,如果您不太关心反向工程,您可以提取jar,然后一次性修复字节码,或者反编译/编辑/编译器;又是罐子,你不能。这是不真实的,大多数java安全性/操作系统敏感代码都可以通过SecurityManager防止,它是自java诞生以来的内置功能。。。只是因为我不知道。。。谢谢你提供的信息。我认为
安全管理器可以满足我的需要,我会试试。你不能用安全管理器运行其他线程,它是全局的。您可以在管理器中检测线程,但这是不同的。