轉(zhuǎn)帖|其它|編輯:郝浩|2010-12-29 15:09:27.000|閱讀 589 次
概述:本文將結(jié)合操作系統(tǒng)的信號機制,來嘗試實現(xiàn)一個簡單的,不依賴功能環(huán)境的Java異步通知功能。
# 界面/圖表報表/文檔/IDE等千款熱門軟控件火熱銷售中 >>
本文將結(jié)合操作系統(tǒng)的信號機制,來嘗試實現(xiàn)一個簡單的,不依賴功能環(huán)境的Java異步通知功能。
沒有特殊說明,本文所有的示例,都是基于Linux。
信號簡介
信號是在軟件層次上對中斷機制的一種模擬,在原理上,一個進程收到一個信號與處理器收到一個中斷請求可以說是一樣的。
通俗來講,信號就是進程間的一種異步通信機制。
典型的例子:
kill -s SIGKILL pid (即kill -9 pid) 立即殺死指定pid的進程。
在上面這個例子中,SIGKILL就是往pid進程發(fā)送的信號。
信號及其效果列表
//docs.google.com/View?id=dtbhrmv_754gh86rcg4
平臺相關(guān)性
信號具有平臺相關(guān)性,不同平臺下能使用的信號種類是有差異的。
在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異步通知,我們需要先選定一種特殊的信號。
通過查看信號列表上的描述,發(fā)現(xiàn) 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);
}
}
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進程發(fā)送信號最佳時機。
發(fā)送信號前,需要先通過 ps 或 jps 獲取java的進程id,然后運行
kill -s SIGUSR2 pid如果在java的stdout 看到 SIGUSR2 is recevied 字樣,說明信號被成功送達了。
在Java編程中使用信號的實際收益
信號作為最原始的進程間異步通信手段,有著諸多局限性的,比如不能傳遞上下文,信號隨時都可能被占用導致沖突,不具備擴展性等,所以對功能性需求來 說,使用它收益甚微。
當然,信號也不是一無是處,除了用作簡單的異步通知外,還可以利用它的進程事件通知功能。
在Java里有一個典型例子,就是 ShutdownHook。
本站文章除注明轉(zhuǎn)載外,均為本站原創(chuàng)或翻譯。歡迎任何形式的轉(zhuǎn)載,但請務(wù)必注明出處、不得修改原文相關(guān)鏈接,如果存在內(nèi)容上的異議請郵件反饋至chenjj@ke049m.cn
文章轉(zhuǎn)載自:網(wǎng)絡(luò)轉(zhuǎn)載