2013-04-11 33 views
6

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

PS。 新线程会调用其他.jar文件中的某些方法,所以我无法修改它。

+0

这是否方法中断响应?你有办法让它退出吗? – assylias 2013-04-11 09:41:17

+2

Err,不会终止JVM意味着什么都结束了吗?无论中断? – Thihara 2013-04-11 09:42:52

+2

@Thihara问题似乎是:我如何停止该线程而不停止主线程。当然System.exit会终止JVM,看起来OP理解这一点。但实际上我可以看到它也可以理解为:新线程确实会调用System.exit,并且我想阻止它这样做。这是不明确的...... – assylias 2013-04-11 09:44:50

回答

2

类:

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) { 
    } 
} 


上startop:

System.setSecurityManager(new MySecurityManager()); 
+0

它工作!〜JVM抛出异常而不退出 – Dozer 2013-04-12 01:15:16

5

你不能。

Terminates the currently running Java Virtual Machine. The argument serves as a status code; by convention, a nonzero status code indicates abnormal termination.

这是javadoc的。

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

+0

*你不能这样做*这是不真实的,大多数java安全/操作系统敏感代码都可以通过SecurityManager来阻止,它是自java开始以来的一种内置功能。 – bestsss 2013-04-11 09:45:14

+0

哦,是的,它滑倒了我的心...但仅仅因为我不知道它...感谢信息。 – Thihara 2013-04-11 10:22:28

5

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

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

编辑:如果你去w /安全管理器,最有可能抛出SecurityException将终止线程。如果没有 - 作弊并抛出一个ThreadDeath。如果仍然不行 - 只需抓住线for(;;) Thread.sleep(10000);后者会泄露线程及其资源,但至少不会杀死您的应用程序。

link to similar question

+0

我认为'安全经理'可以满足我的需求,我会尝试。 – Dozer 2013-04-11 09:49:43

0

使用的Java安全管理器从退出保存你的主线程和运行与安全管理器的其他线程代码。

编辑: 从Tomcat或其他服务器采取主意,他们如何在JSP中处理像<% System.exit(1); %>这样的代码。

+0

您不能运行*其他线程* w /安全管理器,它是全局的。你可以检测管理器中的线程,但这是不同的。 – bestsss 2013-04-11 09:50:58