文章目录

  • 场景
  • 环境
  • 正文
  • SignalHandler类的编写
  • SignalHandler类的绑定
  • 执行脚本
  • 说明
  • 结果
  • 参考链接
  • 总结
  • 随缘求赞


场景

最近,开发的程序是对kafka进行消费,程序开发完毕之后,发现程序的终止一直都是很简单粗暴的kill -9 pid,然后存在数据处理到一半,然后就被干掉,导致最后的结果数据只入了一半便不见了。所以,就这样产生了一个需求:当要结束程序的时候,告知程序要结束了,并等待一些资源的处理完毕和稀缺资源的安全释放。

环境

软件

版本

JDK

8

Centos

7.2

正文

接下来就进去实操环节了,请各位看官接着往下看。

SignalHandler类的编写

我们需要编写一个类来继承sun.misc.SignalHandler,并编写接收到Signal的时候,需要执行的步骤。接下来我展示一个样例代码:

@Slf4j
public class MqKillHandler  implements SignalHandler {

    private ScanMain scanMain;

    public MqKillHandler(ScanMain scanMain) {
        this.scanMain= scanMain;
    }

    /**
     * 注册信号
     * @param signalName
     */
    public void registerSignal(String signalName) {
        Signal signal = new Signal(signalName);
        Signal.handle(signal, this);
    }

    @Override
    public void handle(Signal signal) {
        if (signal.getName().equals("TERM")) {
            // 程序关闭
            try {
                log.info("程序关闭,正在关闭相关资源");

                startScanMain.closeAllThread();

                log.info("程序关闭完毕");

				// 退出程序
                System.exit(0);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}

SignalHandler类的绑定

编写了SignalHandler类之后,就需要在程序里面调用并绑定对应的Signal的接收,代码如下:

log.info("绑定 程序关闭信号,实现程序正常关闭 ");
// 设置 程序关闭线程
MqKillHandler mqKillHandler = new MqKillHandler(this);
mqKillHandler.registerSignal("TERM");

执行脚本

接下来,启动脚本之后,我们等待运行一段时间之后,执行以下脚本:

kill -15 $pid

说明

15就是对应的信号量,代表SIGTERM,就是本文程序里面指定的信号量。下面是官网的解释:

SIGTERM - This signal requests a process to stop running. This signal can be ignored. The process is given time to gracefully shutdown. When a program gracefully shuts down, that means it is given time to save its progress and release resources. In other words, it is not forced to stop. SIGINT is very similar to SIGTERM.

结果

执行kill命令之后,从下面的截图可以得出,我们的程序是成功地达到了目标,有计划地将资源进行释放,比较完善地终止了我们的程序。

java 信号量 tryacquire java 信号处理_SignalHandler

参考链接

man1/kill.1list-of-kill-signalssignalkill-commands-and-signals

总结

一些程序需要有步骤地进行资源结束,否则会造成资源浪费和数据丢失。根据linux内部机制的信号量Java提供的SignalHandler类来处理这些事情,简单快捷高效。

java 信号量 tryacquire java 信号处理_java_02

随缘求赞

如果我的文章对大家产生了帮忙,可以在文章底部点个赞或者收藏;

如果有好的讨论,可以留言;

java 信号量 tryacquire java 信号处理_java 信号量 tryacquire_03