java 程序間通訊的有幾種方法?
歡迎訪問我的技術群425783133
程序間通訊的方法主要有以下幾種:
(1)管道(Pipe):管道可用於具有親緣關係程序間的通訊,允許一個程序和另一個與它有共同祖先的程序之間進行通訊。
(2)命名管道(named pipe):命名管道克服了管道沒有名字的限制,因此,除具有管道所具有的功能外,它還允許無親緣關 系 程序間的通訊。命名管道在檔案系統中有對應的檔名。命名管道通過命令mkfifo或系統呼叫mkfifo來建立。
(3)訊號(Signal):訊號是比較複雜的通訊方式,用於通知接受程序有某種事件發生,除了用於程序間通訊外,程序還可以傳送 訊號給程序本身;linux除了支援Unix早期訊號語義函式sigal外,還支援語義符合Posix.1標準的訊號函式sigaction(實際上,該函式是基於BSD的,BSD為了實現可靠訊號機制,又能夠統一對外介面,用sigaction函式重新實現了signal函式)。
(4)訊息(Message)佇列:訊息佇列是訊息的連結表,包括Posix訊息佇列system V訊息佇列。有足夠許可權的程序可以向佇列中新增訊息,被賦予讀許可權的程序則可以讀走佇列中的訊息。訊息佇列克服了訊號承載資訊量少,管道只能承載無格式位元組流以及緩衝區大小受限等缺
(5)共享記憶體:使得多個程序可以訪問同一塊記憶體空間,是最快的可用IPC形式。是針對其他通訊機制執行效率較低而設計的。往往與其它通訊機制,如訊號量結合使用,來達到程序間的同步及互斥。
(6)記憶體對映(mapped memory):記憶體對映允許任何多個程序間通訊,每一個使用該機制的程序通過把一個共享的檔案對映到自己的程序地址空間來實現它。
(7)訊號量(semaphore):主要作為程序間以及同一程序不同執行緒之間的同步手段。
(8)套介面(Socket):更為一般的程序間通訊機制,可用於不同機器之間的程序間通訊。起初是由Unix系統的BSD分支開發出來的,但現在一般可以移植到其它類Unix系統上:Linux和System V的變種都支援套接字。
而在java中我們實現多執行緒間通訊則主要採用"共享變數"和"管道流"這兩種方法
方法一 通過訪問共享變數的方式(注:需要處理同步問題)
方法二 通過管道流
其中方法一有兩種實現方法,即
方法一a)通過內部類實現執行緒的共享變數
程式碼如下:
public
class Innersharethread {
public
static void main(String[] args) {
Mythread mythread = new
Mythread();
mythread.getThread().start();
mythread.getThread().start();
mythread.getThread().start(); mythread.getThread().start();
}
}
class
Mythread {
int
index = 0 ;
private class
InnerThread extends
Thread {
public
synchronized void
run() {
while
( true ) {
System.out.println(Thread.currentThread().getName()
+ "is running and index is " + index++);
}
}
}
public
Thread getThread() {
return
new InnerThread(); }
}
/**
* 通過內部類實現執行緒的共享變數
*
*/
public
class Innersharethread {
public
static void main(String[] args) {
Mythread mythread = new
Mythread();
mythread.getThread().start();
mythread.getThread().start();
mythread.getThread().start();
mythread.getThread().start();
}
}
class
Mythread {
int
index = 0 ;
private class
InnerThread extends
Thread {
public
synchronized void
run() {
while
( true ) {
System.out.println(Thread.currentThread().getName()
+ "is running and index is " + index++);
}
}
}
public
Thread getThread() {
return
new InnerThread();
}
}
|
b)通過實現Runnable介面實現執行緒的共享變數
程式碼如下:
public
class Interfacaesharethread {
public
static void main(String[] args) {
Mythread mythread = new
Mythread();
new
Thread(mythread).start();
new
Thread(mythread).start();
new
Thread(mythread).start();
new
Thread(mythread).start();
}
}
/* 實現Runnable介面 */
class Mythread implements Runnable {
int index = 0;
public synchronized void run() {
while (true)
System.out.println(Thread.currentThread().getName() + "is running and
the index is " + index++);
}
}
/**
* 通過實現Runnable介面實現執行緒的共享變數
*/
public class Interfacaesharethread {
public static void main(String[] args) {
Mythread mythread = new Mythread();
new Thread(mythread).start();
new Thread(mythread).start();
new Thread(mythread).start();
new Thread(mythread).start();
}
}
/* 實現Runnable介面 */
class
Mythread implements
Runnable {
int
index = 0 ;
public
synchronized void
run() {
while
( true )
System.out.println(Thread.currentThread().getName() + "is running and
the index is " + index++);
}
}
|
方法二(通過管道流):
程式碼如下:
public
class
CommunicateWhitPiping {
public
static
void
main(String[] args) {
/**
* 建立管道輸出流
*/
PipedOutputStream pos =
new
PipedOutputStream();
/**
* 建立管道輸入流
*/
PipedInputStream pis =
new
PipedInputStream();
try
{
/**
* 將管道輸入流與輸出流連線 此過程也可通過過載的建構函式來實現
*/
pos.connect(pis);
}
catch
(IOException e) {
e.printStackTrace();
}
/**
* 建立生產者執行緒
*/
Producer p =
new
Producer(pos);
/**
* 建立消費者執行緒
*/
Consumer c =
new
Consumer(pis);
/**
* 啟動執行緒
*/
p.start();
c.start();
}
}
/**
* 生產者執行緒(與一個管道輸入流相關聯)
*
*/
class
Producer
extends
Thread {
private
PipedOutputStream pos;
public
Producer(PipedOutputStream pos) {
this
.pos = pos;
}
public
void
run() {
int
i =
8
;
try
{
pos.write(i);
}
catch
(IOException e) {
e.printStackTrace();
}
}
}
/**
* 消費者執行緒(與一個管道輸入流相關聯)
*
*/
class
Consumer
extends
Thread {
private
PipedInputStream pis;
public
Consumer(PipedInputStream pis) {
this
.pis = pis;
}
public
void
run() {
try
{
System.out.println(pis.read());
}
catch
(IOException e) {
e.printStackTrace();
}
}
}
歡迎訪問我的技術群425783133