2013-04-11 61 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