最近一直在做测试方面的事情,被测的一些功能需要连接到FTP服务器上。而我在做本地测试时为了方便,就使用java写了一个简单的ftp服务器,可以在命令行下直接启动运行。

当时在main函数里是这样写的。

1
2
3
4
5
6
7
public class App {

    public static void main(String[] args) {
FtpServer ftpServer = new FtpServer();
ftpServer.start();
}
}

然后在命令行运行java -jar ftpserver.jar就可以启动这个FTP服务。一切都很完美。当我想关闭FTP服务时,直接按了Ctrl + C来终止了这个JVM实例。但是我发现ftpserver.jar这个文件删不了了,原因是虽然我终止了该JVM实例,但是FTP服务器并没有被正确的退出。

那么如何实现在按Ctrl+C终止该JVM实例时,能够让程序调用FtpServer中的stop方法来关闭FTP服务?我想在Google上寻找答案,但是连续换了几个关键词都没找到解决方案。

这个时候我都有点差点放弃了,心想反正也不是一个很严重的问题。后来想到不如在StackOverFlow上问一下吧。说实话虽然我经常上StackOverFlow,但是很少在上面问问题。

我在StackOverFlow上发布了这个问题,链接如下。
http://stackoverflow.com/questions/21108059/stop-the-process-when-press-command-c-in-terminal

过了不到20分钟,就收到了一个回答。

从上面可以看出,其实我这个问题之前已经有人问过了,并且收到了满意的答案。我根据回答中提供的链接,很快实现了方法。

1
2
3
4
5
6
7
8
9
10
11
12
public static void main(String[] args) {
final FtpServer ftpServer = new FtpServer(); Runtime.getRuntime().addShutdownHook(new Thread() {
@Override
public void run() {
ftpServer.stop();
}
}); ftpServer.start();
}

在oracle的官方文档中有对addShutdownHook方法的详细解释。

通过文档可以看出JVM在两种事件下会响应shutdown:

  1. 程序正常退出,比如最后的非后台线程退出或System.exit方法被调用。

  2. 用户终止了JVM,比如按下Ctrl+C,或者登出或关闭系统。

某些情况下JVM是不会响应shutdown的,比如直接用kill命令杀死进程。JVM在shutdown时,会自动触发注册的hook线程,并以并行的方式来运行,JVM并不保证这些hook的调用顺序。

通过这个小事件给了我两个启示:

  1. 当碰到技术困难时,不要轻言放弃,努力找出解决方案。即使找不到完美的解决方案,也要想一些替代方案。

  2. 在StackOverFlow上问问题时不要太着急,先查找下有没有类似的已经解决的问题,这样可以节省时间。

记一次在StackOverFlow上问问题的经历的更多相关文章

  1. 记一次Linux服务器上查杀木马经历

    开篇前言 Linux服务器一直给我们的印象是安全.稳定.可靠,性能卓越.由于一来Linux本身的安全机制,Linux上的病毒.木马较少,二则由于宣称Linux是最安全的操作系统,导致很多人对Linux ...

  2. 老码农教你在 StackOverflow 上谈笑风生

    作为一个高大上的码农,你肯定用到过 StackOverflow,必须的.会有人否定这个断言么?那他恐怕不是真正的码农,或者说还没入门.StackOverflow 对于码农的重要性,基本就和诸葛亮对刘备 ...

  3. 为什么 StackOverflow 上的代码片段会摧毁你的项目?

    昨天公司里碰到一件令人哑然失笑的事情.帮朋友公司做的一个项目,做SIT测试的时候发现一些bug,仔细查了下原因,原来是因为当初觉得这个项目比较简单,交给了几个新入职的新丁,也算是给他们练练手,结果其中 ...

  4. 我发现:在StackOverflow上拯救歪果仁十分有意思!

    菊长:火星特工们!今天是周五了,大家有什么提议? BeJavaGod:报告菊长!我发现,在StackOverflow上拯救歪果仁十分有意思! 噗哈哈,时不时遇到问题会使用到StackOverflow, ...

  5. stackoverflow上关于iOS的票数最多(最常见)的15个问题

    搞编程做项目的,没碰到bug.遇到问题,基本不可能.stackoverflow就是一个大型的开放的FAQ平台,你是问题制造者,也是答案提供者.本文列出至今stackoverflow上关于iOS的票数最 ...

  6. Stackoverflow上有哪些声望高or值得关注的国人

    Stackoverflow上有哪些声望高/值得关注的国人? 以下回答并不严格按照 Reputation 排名来列,也不收录不确定是Chinese(中国人或华人)的用户,欢迎补充- 1.李杨 @Li L ...

  7. 记一次在咸鱼上购买 MacBook Pro 的经历

    前言 以前一直用的是 windows 的,但是最近特别想买个 macOS 的.其实不是为了其他什么目的,只是涉及到开发 macOS更接近 linux 系统,一直没使用过所以就想尝试体验下,而且现在很多 ...

  8. 屌丝giser成长记-研一篇(上)

    2011年本科毕业之后,我选择了保研GIS研究生,继续了我的GIS研究生涯,读研的童鞋们注意了,读研选择什么样的导师很重要,因为不同的导师有不同的人脉,从浅一点的来说,导师手头的开发项目多的话,你自己 ...

  9. 在stackoverflow上使用markdown

    stackoverflow流派的markdown. Code and Preformatted Text 缩进四个空格,就可以写代码片段了 def hello(): print "hello ...

随机推荐

  1. Python list方法总结

    1. 向列表的尾部添加一个新的元素 append(...) L.append(object) -- append object to end 1 2 3 4 >>> a = ['sa ...

  2. 关于 this 和 prototype 的理解

    1:this 的理解比较好的书是 <Javascript语言精粹> 平时我们全局写 var a = 1, 其实就是 window.a = 1; var f = function(){},  ...

  3. sql子查询 嵌套SELECT语句

    嵌套SELECT语句也叫子查询,一个 SELECT 语句的查询结果能够作为另一个语句的输入值.子查询不但能够出现在Where子句中,也能够出现在from子句中,作为一个临时表使用,也能够出现在sele ...

  4. python模块使用案例

    python模块使用案例 一.使用MySQLdb模块代码示例: # 导入 MySQLdb模块 import MySQLdb # 和服务器建立链接,host是服务器ip,我的MySQL数据库搭建在本机, ...

  5. jQuery触发<a>标签的点击事件无效

    <a id="workFrame" href="pages/work.html" target="FrameBox">首页< ...

  6. iOS中UITableView数据源刷新了,但tableview当中的cell没有刷新

    你会不会遇到通过断点查看数据源模型的确刷新了,但是tableview没有刷新的情况,我遇到了,并通过下面的方法解决了,供大家参考! 在tableview中的数据源代理方法 p.p1 { margin: ...

  7. Train Problem I hdu 1022(栈)

    http://acm.split.hdu.edu.cn/showproblem.php?pid=1022 题意:给出火车的进站与出站顺序,判断是否可以按照给出的出站顺序出站. #include < ...

  8. PHP高级——抽象类与接口的区别(转)

    在学习PHP面向对象时,都会在抽象类与接口上迷惑,作用差不多为什么还那么容易混淆,何不留一去一?但是事实上两者的区别还是很大的,如果能够很好地运用PHP的两个方法,面向对象的程序设计将会更加合理.清晰 ...

  9. 揭开HTTP网络协议神秘面纱系列(二)

    HTTP报文内的HTTP信息 HTTP协议交互的信息被称为HTTP报文,请求端的HTTP报文叫做请求报文,响应端的叫做响应报文. HTTP为了提升传输速率,其在传输数据时,按照数据原样进行压缩传输,相 ...

  10. SQL Server 查看物理页存储

    创建测试表 Use Test create table dbo.employee( emp_lname varchar(12) not null, emp_fname varchar(12)not n ...