zoukankan      html  css  js  c++  java
  • Java中处理Linux信号量

    为了防止无良网站的爬虫抓取文章,特此标识,转载请注明文章出处。LaplaceDemon/ShiJiaqi。

    http://www.cnblogs.com/shijiaqi1066/p/5976361.html

    Linux信号量

    Linux信号量是一种比较原始的进程通信手段。有很多缺陷,可却是理解操作系统的基础概念。

    使用 kill -l 查询机器上所有信号量,不同操作系统上显示的不一样。

    Java中处理信号量

    通常Java只支持一种信号量的捕获,即使用runtime.addShutdownHook()对退出信号做处理。

    Runtime.getRuntime().addShutdownHook(handleThread);    //handleThread是信号处理线程。

    按照Java标准,Java不支持其他信号的处理,因为这涉及到操作系统,而不是JVM层面的事情。但按照Java一贯的尿性,很多看似没办法的特性都可以通过 sun.misc 包提供的一系列黑魔法来实现。

    原则上sun.misc包中的内容不被推荐使用,所以编译器会发出警告。需要添加 @SuppressWarnings("restriction") 来消除警告。

    package sjq.signal.java;
    
    import sun.misc.Signal;
    import sun.misc.SignalHandler;
    
    @SuppressWarnings("restriction")
    public class SignalTest {
        public static void main(String[] args) throws InterruptedException {
            // 信号处理实例
            MySignalHandler mySignalHandler = new MySignalHandler();
            
            // 注册对指定信号的处理
            Signal.handle(new Signal("TERM") ,mySignalHandler);    // kill or kill -15
            Signal.handle(new Signal("INT"), mySignalHandler);     // kill -2
            
            System.out.println("[Thread:"+Thread.currentThread().getName() + "] is sleep" );
            while(true) Thread.sleep(1000);
        }
    }
    
    @SuppressWarnings("restriction")
    class MySignalHandler implements SignalHandler {
    
        @Override
        public void handle(Signal signal) {
            
            // 信号量名称
            String name = signal.getName();
            // 信号量数值
            int number = signal.getNumber();
            
            // 当前进程名
            String currentThreadName = Thread.currentThread().getName();
            
            System.out.println("[Thread:"+currentThreadName + "] receved signal: " + name + " == kill -" + number);
            if(name.equals("TERM")){
                System.exit(0);
            }
        }
        
    }

    在命令行中输入多个kill -2和一个kill后,打印如下内容:

    [Thread:main] is sleep
    [Thread:SIGINT handler] receved signal: INT == kill -2
    [Thread:SIGINT handler] receved signal: INT == kill -2
    [Thread:SIGINT handler] receved signal: INT == kill -2
    [Thread:SIGINT handler] receved signal: INT == kill -2
    [Thread:SIGINT handler] receved signal: INT == kill -2
    [Thread:SIGINT handler] receved signal: INT == kill -2
    [Thread:SIGINT handler] receved signal: INT == kill -2
    [Thread:SIGINT handler] receved signal: INT == kill -2
    [Thread:SIGINT handler] receved signal: INT == kill -2
    [Thread:SIGTERM handler] receved signal: TERM == kill -15

    可以看出Java对每个信号都启动一个线程进行处理。注册TERM信号,就启动"SIGTERM handler" 线程。即便主线程被阻塞,信号依然可以得到处理。

    由于对信号的处理是多线程的,所以应保证信号处理实例SignalHandler应该是线程安全的。

    对于某些信号运行中可能会抛出异常:

    java.lang.IllegalArgumentException: Signal already used by VM: USR1

    这是因为某些信号可能已经被JVM占用,USR1、USR2,可以考虑用其它信号代替。

    为了防止无良网站的爬虫抓取文章,特此标识,转载请注明文章出处。LaplaceDemon/ShiJiaqi。

    http://www.cnblogs.com/shijiaqi1066/p/5976361.html

  • 相关阅读:
    洛谷P1865 A%B Problem
    树状数组的操作
    树状数组的基础知识
    卡常优化中最为奇怪的操作
    inline的用法
    快速读入的方法
    P1059 明明的随机数及unique去重的用法
    P3376 网络最大流 【模板】
    Gym
    HDU
  • 原文地址:https://www.cnblogs.com/shijiaqi1066/p/5976361.html
Copyright © 2011-2022 走看看