Java中处理Linux信号量

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

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

 

 

Linux信号量

Linux信号量是一种比较原始的进程通讯手段。有不少缺陷,可倒是理解操做系统的基础概念。安全

使用 kill -l 查询机器上全部信号量,不一样操做系统上显示的不同。多线程

 

Java中处理信号量

一般Java只支持一种信号量的捕获,即便用runtime.addShutdownHook()对退出信号作处理。ide

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

按照Java标准,Java不支持其余信号的处理,由于这涉及到操做系统,而不是JVM层面的事情。但按照Java一向的尿性,不少看似没办法的特性均可以经过 sun.misc 包提供的一系列黑魔法来实现。网站

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

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占用,USR一、USR2,能够考虑用其它信号代替。

 

 

 

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

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

相关文章
相关标签/搜索