Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1372572
  • 博文数量: 205
  • 博客积分: 6732
  • 博客等级: 准将
  • 技术积分: 2835
  • 用 户 组: 普通用户
  • 注册时间: 2008-09-04 17:59
文章分类

全部博文(205)

文章存档

2016年(1)

2015年(10)

2014年(1)

2013年(39)

2012年(23)

2011年(27)

2010年(21)

2009年(55)

2008年(28)

我的朋友

分类: Java

2013-08-20 10:42:42

在linux/unix下,你会怎么中止一个java应用或进程?
多数人可能会回答 kill -9 pid,这是一种在多数情况下正确的做法。不过本文打算阐述使用kill -9带来的一些问题,并给出另一种标准的kill方式。

标准中断信号

在Linux信号机制中,存在多种进程中断信号( )。其中比较典型的有 SIGNKILL(9) 和 SIGNTERM(15).

SIGNKILL(9) 和 SIGNTERM(15) 的区别在于:
SIGNKILL(9) 的效果是立即杀死进程. 该信号不能被阻塞, 处理和忽略。
SIGNTERM(15) 的效果是正常退出进程,退出前可以被阻塞或回调处理。并且它是Linux缺省的程序中断信号。

由此可见,SIGNTERM(15) 才是理论上标准的kill进程信号。
那使用 SIGNKILL(9) 又有什么错呢?

SIGNKILL(9) 带来的问题

先看一段程序

点击(此处)折叠或打开

  1. /**
  2.      * Shutdown Hook Presentation
  3.      *
  4.      * @author Ken Wu
  5.      */
  6.     public class ShutdownHookTest {
  7.        
  8.         private static final void shutdownCallback() {
  9.             System.out.println("Shutdown callback is invoked.");
  10.         }
  11.        
  12.         public static void main(String[] args) throws InterruptedException {
  13.             Runtime.getRuntime().addShutdownHook(new Thread() {
  14.        
  15.                 @Override
  16.                 public void run() {
  17.                     shutdownCallback();
  18.                 }
  19.        
  20.             });
  21.             Thread.sleep(10000);
  22.         }
  23.        
  24.     }

在上面这段程序中,我使用Runtime为当前java进程添加了一个ShutdownHook,它的作用是在java正常退出时,执行shutdownCallback()这个回调方法。
此时,如果你试验过在java进程未自动退出前,执行 kill -9 pid,即发送 SIGNKILL 信号,会发现这个回调接口是不会被执行的。这是SIGNKILL信号起的作用。

对于我这个简单的测试用例来说,不被执行也无大碍。但是,如果你的真实系统中有需要在java进程退出后,释放某些资源。
而这个释放动作,因为SIGNKILL被忽略了,那就可能造成一些问题。

所以,推荐大家使用标准的kill进程方式,即 kill -15 pid。

摘自:

阅读(2618) | 评论(0) | 转发(1) |
给主人留下些什么吧!~~