IT技术博客大学习 共学习 共进步
全部 移动开发 后端 数据库 AI 算法 安全 DevOps 前端 设计 开发者

基于OS信号实现Java异步通知

淘宝JAVA中间件团队博客 2011-06-23 13:35:53 累计浏览 3,549 次
本机暂存

    本文将结合操作系统的信号机制,来尝试实现一个简单的,不依赖功能环境的Java异步通知功能。

     没有特殊说明,本文所有的示例,都是基于Linux。

信号简介

    信号是在软件层次上对中断机制的一种模拟,在原理上,一个进程收到一个信号与处理器收到一个中断请求可以说是一样的。

     通俗来讲,信号就是进程间的一种异步通信机制。

    典型的例子:

     kill -s SIGKILL pid (即kill -9 pid) 立即杀死指定pid的进程。

     在上面这个例子中,SIGKILL就是往pid进程发送的信号。

    信号及其效果列表

     http://docs.google.com/View?id=dtbhrmv_754gh86rcg4

平台相关性

    信号具有平台相关性,不同平台下能使用的信号种类是有差异的。

    在Linux下支持的信号(对比信号列表查看描述)

     SEGV, ILL, FPE, BUS, SYS, CPU, FSZ, ABRT, INT, TERM, HUP, USR1, USR2, QUIT, BREAK, TRAP, PIPE

    在Windows下支持的信号

     SEGV, ILL, FPE, ABRT, INT, TERM, BREAK

信号选择

    为了不干扰正常信号的运作,又能模拟Java异步通知,我们需要先选定一种特殊的信号。

     通过查看信号列表上的描述,发现 SIGUSR1 和 SIGUSR2 是允许用户自定义的信号。

     那么选择它们,理论上就不会影响正常功能了。

    这里我选用了USR2作为传递信号。原因是USR1有可能已被其他APP占用。

实例代码

import sun.misc.Signal;
import sun.misc.SignalHandler;

/**
 * Java Signal Test
 * @author Ken Wu
 *
 */
@SuppressWarnings("restriction")
public class TestSignal implements SignalHandler {

        private void signalCallback(Signal sn) {
               System.out.println(sn.getName() + "is recevied.");
        }

        @Override
        public void handle(Signal signalName) {
               signalCallback(signalName);
        }

        public static void main(String[] args) throws InterruptedException {
               TestSignal testSignalHandler = new TestSignal();
               // install signals
               Signal sig = new Signal("USR2");
               Signal.handle(sig, testSignalHandler);
               Thread.sleep(15000);
        }

}

    Sun为我们提供了2个方便安装和替换信号处理器的工具类。

     sun.misc.Signal

     sun.misc.SignalHandler

    将上面的代码编译后,运行,会暂停15秒,此时,是你给java进程发送信号最佳时机。

     发送信号前,需要先通过 ps 或 jps 获取java的进程id,然后运行

kill -s SIGUSR2 pid

    如果在java的stdout 看到 SIGUSR2 is recevied 字样,说明信号被成功送达了。

在Java编程中使用信号的实际收益

    信号作为最原始的进程间异步通信手段,有着诸多局限性的,比如不能传递上下文,信号随时都可能被占用导致冲突,不具备扩展性等,所以对功能性需求来说,使用它收益甚微。

    当然,信号也不是一无是处,除了用作简单的异步通知外,还可以利用它的进程事件通知功能。

     在Java里有一个典型例子,就是 ShutdownHook。

    转载请注明原文链接:http://kenwublog.com/java-asynchronous-notify-based-on-signal

同分类推荐文章

  1. 等了十年的 Go 链式管道,终于来了:seq 让你像写 Scala 一样写 Go (2026-06-25 18:38:18)
  2. Go 实验特性详解 (2026-06-21 10:05:27)
  3. amd64 微架构级别对 Go 程序性能提升多少? (2026-06-21 09:38:49)

查看更多 后端 文章 →

建议继续学习

  1. SmartSprites - 命令行形式的CSS Sprites生成器 (累计阅读 123,894)
  2. Java开发岗位面试题归类汇总 (累计阅读 22,155)
  3. android 开发入门 (累计阅读 19,527)
  4. 我的PHP,Python和Ruby之路 (累计阅读 13,146)
  5. HashMap解决hash冲突的方法 (累计阅读 12,652)
  6. 一个大二学生有关如何成为一名软件工程师的疑问及答复 (累计阅读 9,178)
  7. Java程序员应该知道的10个eclipse调试技巧 (累计阅读 8,011)
  8. 如何让员工忠于公司? (累计阅读 7,936)
  9. Java技术路线 (累计阅读 7,725)
  10. 聊聊ThoughtWorks面试 (累计阅读 7,612)