轉(zhuǎn)帖|其它|編輯:郝浩|2010-12-29 15:09:27.000|閱讀 587 次
概述:本文將結(jié)合操作系統(tǒng)的信號(hào)機(jī)制,來(lái)嘗試實(shí)現(xiàn)一個(gè)簡(jiǎn)單的,不依賴功能環(huán)境的Java異步通知功能。
# 界面/圖表報(bào)表/文檔/IDE等千款熱門(mén)軟控件火熱銷(xiāo)售中 >>
本文將結(jié)合操作系統(tǒng)的信號(hào)機(jī)制,來(lái)嘗試實(shí)現(xiàn)一個(gè)簡(jiǎn)單的,不依賴功能環(huán)境的Java異步通知功能。
沒(méi)有特殊說(shuō)明,本文所有的示例,都是基于Linux。
信號(hào)簡(jiǎn)介
信號(hào)是在軟件層次上對(duì)中斷機(jī)制的一種模擬,在原理上,一個(gè)進(jìn)程收到一個(gè)信號(hào)與處理器收到一個(gè)中斷請(qǐng)求可以說(shuō)是一樣的。
通俗來(lái)講,信號(hào)就是進(jìn)程間的一種異步通信機(jī)制。
典型的例子:
kill -s SIGKILL pid (即kill -9 pid) 立即殺死指定pid的進(jìn)程。
在上面這個(gè)例子中,SIGKILL就是往pid進(jìn)程發(fā)送的信號(hào)。
信號(hào)及其效果列表
//docs.google.com/View?id=dtbhrmv_754gh86rcg4
平臺(tái)相關(guān)性
信號(hào)具有平臺(tái)相關(guān)性,不同平臺(tái)下能使用的信號(hào)種類是有差異的。
在Linux下支持的信號(hào)(對(duì)比信號(hào)列表查看描述)
SEGV, ILL, FPE, BUS, SYS, CPU, FSZ, ABRT, INT, TERM, HUP, USR1, USR2, QUIT, BREAK, TRAP, PIPE
在Windows下支持的信號(hào)
SEGV, ILL, FPE, ABRT, INT, TERM, BREAK
信號(hào)選擇
為了不干擾正常信號(hào)的運(yùn)作,又能模擬Java異步通知,我們需要先選定一種特殊的信號(hào)。
通過(guò)查看信號(hào)列表上的描述,發(fā)現(xiàn) SIGUSR1 和 SIGUSR2 是允許用戶自定義的信號(hào)。
那么選擇它們,理論上就不會(huì)影響正常功能了。
這里我選用了USR2作為傳遞信號(hào)。原因是USR1有可能已被其他APP占用。
實(shí)例代碼
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);
}
}
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個(gè)方便安裝和替換信號(hào)處理器的工具類。
sun.misc.Signal
sun.misc.SignalHandler
將上面的代碼編譯后,運(yùn)行,會(huì)暫停15秒,此時(shí),是你給java進(jìn)程發(fā)送信號(hào)最佳時(shí)機(jī)。
發(fā)送信號(hào)前,需要先通過(guò) ps 或 jps 獲取java的進(jìn)程id,然后運(yùn)行
kill -s SIGUSR2 pid如果在java的stdout 看到 SIGUSR2 is recevied 字樣,說(shuō)明信號(hào)被成功送達(dá)了。
在Java編程中使用信號(hào)的實(shí)際收益
信號(hào)作為最原始的進(jìn)程間異步通信手段,有著諸多局限性的,比如不能傳遞上下文,信號(hào)隨時(shí)都可能被占用導(dǎo)致沖突,不具備擴(kuò)展性等,所以對(duì)功能性需求來(lái) 說(shuō),使用它收益甚微。
當(dāng)然,信號(hào)也不是一無(wú)是處,除了用作簡(jiǎn)單的異步通知外,還可以利用它的進(jìn)程事件通知功能。
在Java里有一個(gè)典型例子,就是 ShutdownHook。
本站文章除注明轉(zhuǎn)載外,均為本站原創(chuàng)或翻譯。歡迎任何形式的轉(zhuǎn)載,但請(qǐng)務(wù)必注明出處、不得修改原文相關(guān)鏈接,如果存在內(nèi)容上的異議請(qǐng)郵件反饋至chenjj@fc6vip.cn
文章轉(zhuǎn)載自:網(wǎng)絡(luò)轉(zhuǎn)載