java-system-exit问题

System.exit(1)有什么用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
public class SystemExitDemo {

public static void main(String[] args) {

System.out.println("begin...");

doSometings();

try {
//主线程阻塞一会儿,让子线程先执行完
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("end...");
}

public static void doSometings() {

Thread thread = new Thread() {

@Override
public void run() {
System.out.println(111);
System.exit(1);
}
};
thread.start();
}

}
1
2
3
4
begin...
111

Process finished with exit code 1

从输出结果看,System.exit(status)会退出整个jvm,而不只是当前线程。

自定义SecurityManager

System.exit(status) ==》 Runtime.getRuntime().exit(status)

1
2
3
4
5
6
7
public void exit(int status) {
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkExit(status);
}
Shutdown.exit(status);
}

如果想要控制exit,需要自定义SecurityManager来处理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48

public class MySecurityManager extends SecurityManager {

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


public class SystemExitDemo {

public static void main(String[] args) {

System.setSecurityManager(new MySecurityManager());
System.out.println("begin...");

try {
doSometings();
} catch (Exception e) {
e.printStackTrace();
}

try {
//主线程阻塞一会儿,让子线程先执行完
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("end...");

}

public static void doSometings() {

Thread thread = new Thread() {

@Override
public void run() {
System.out.println(111);
System.exit(1);
}
};
thread.start();
}

}

输出:

1
2
3
4
5
6
7
8
begin...
111
Exception in thread "Thread-0" java.lang.SecurityException: not allow user System.exit
at com.mydemo.MySecurityManager.checkExit(MySecurityManager.java:8)
at java.lang.Runtime.exit(Runtime.java:107)
at java.lang.System.exit(System.java:962)
at com.mydemo.SystemExitDemo$1.run(SystemExitDemo.java:32)
end...

总结

  1. System.exit(status)默认情况下是暴露给SecurityManager来控制并退出jvm的
  2. 只是在程序中达到退出线程的目的,应该使用异常而不是exit