本文目錄一覽:
- 1、java 進程間通訊的有幾種方法?
- 2、請問java管道流是用來幹嘛的?通俗的說一下
- 3、java 中的管道流是怎麼用的?它與不同的輸入輸出流的區別在哪裡?
- 4、java如何實現進程間的通信
- 5、java 管道流
- 6、java怎樣截獲控制台輸出
java 進程間通訊的有幾種方法?
進程間通信的方法主要有以下幾種:
(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();
}
}
}
請問java管道流是用來幹嘛的?通俗的說一下
IO流只有一種表現形態,即要麼輸出,要麼輸入。這樣就有了InputStream和OutputStream。再說一點,流是可以相互包含的,即輸入流可以接受輸出對象,輸出流可以接受輸入對象(具體看API方法就可以了)。
接着看看管道流的構造器,可以創建默認構造器(未連接),也可以構造有輸入或輸出流的管道流。創建了以後,調用connect方法,可以將輸入流與輸出流進行連接
java 中的管道流是怎麼用的?它與不同的輸入輸出流的區別在哪裡?
在Java的IO流中有一種很非凡的流就是管道流類:PipedInputStream PipedOutputStream.這兩個類的實例對象必須要通過connect方法連接.
其實看這麼一個程序就知道了管道流類的使用方法.
//sender.java
import java.io.*;
import java.util.*;
public class sender extends Thread
{
PipedOutputStream out = new PipedOutputStream();
public PipedOutputStream getOut()
{
return out;
}
public void run()
{
String str = “Hello,receiver ! I`m sender\n”;
try
{
out.write(str.getBytes());
out.close();
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
//receiver.java
import java.io.*;
import java.util.*;
public class receiver extends Thread
{
PipedInputStream in = new PipedInputStream();
public PipedInputStream getIn()
{
return in;
}
public void run()
{
byte [] buf = new byte[1024];
try
{
int len = in.read(buf);
System.out.println(“the following is from sender:\n”+new String(buf,0,len));
in.close();
}catch(Exception e)
{
e.printStackTrace();
}
}
}
//TestPiped.java
import java.io.*;
class TestPiped
{
public static void main(String [] args)
{
sender s = new sender();
receiver r = new receiver();
PipedOutputStream out = s.getOut();
PipedInputStream in = r.getIn();
try
{
in.connect(out);
s.start();
r.start();
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
這個程序的功能是sender發送”Hello,receiver ! I`m sender”給receiver然後receiver接受後顯示出來並且在前面加上”the following is from sender”的信息.要注重的就是PipedInputStream和PipedOutputStream分別用兩個線程傳送數據.
java如何實現進程間的通信
傳統的進程間通信的方式有大致如下幾種:
(1) 管道(PIPE)
(2) 命名管道(FIFO)
(3) 信號量(Semphore)
(4) 消息隊列(MessageQueue)
(5) 共享內存(SharedMemory)
(6) Socket
Java如何支持進程間通信。我們把Java進程理解為JVM進程。很明顯,傳統的這些大部分技術是無法被我們的應用程序利用了(這些進程間通信都是靠系統調用來實現的)。但是Java也有很多方法可以進行進程間通信的。
除了上面提到的Socket之外,當然首選的IPC可以使用Rmi,或者Corba也可以。另外Java nio的MappedByteBuffer也可以通過內存映射文件來實現進程間通信(共享內存)。
java 管道流
管道流實際上就是整行的讀取和寫入,不用每個字節每個字節的讀取和寫入
讀寫是兩個不同的分支,通常都是分開單獨使用的。
可以通過BufferedReader 流的形式進行流緩存,之後通過readLine方法獲取到緩存的內容。
BufferedReader bre = null;
try {
String file = “D:/test/test.txt”;
bre = new BufferedReader(new FileReader(file));//此時獲取到的bre就是整個文件的緩存流
while ((str = bre.readLine())!= null) // 判斷最後一行不存在,為空結束循環
{
System.out.println(str);//原樣輸出讀到的內容
};
備註一: 流用完之後必須close掉,如上面的就應該是:bre.close(),否則bre流會一直存在,直到程序運行結束。
可以通過“FileOutputStream”創建文件實例,之後過“OutputStreamWriter”流的形式進行存儲,舉例:
OutputStreamWriter pw = null;//定義一個流
pw = new OutputStreamWriter(new FileOutputStream(“D:/test.txt”),”GBK”);//確認流的輸出文件和編碼格式,此過程創建了“test.txt”實例
pw.write(“我是要寫入到記事本文件的內容”);//將要寫入文件的內容,可以多次write
pw.close();//關閉流
備註二:文件流用完之後必須及時通過close方法關閉,否則會一直處於打開狀態,直至程序停止,增加系統負擔。
java怎樣截獲控制台輸出
要在文本框中顯示控制台輸出,我們必須用某種方法“截取”控制台流。換句話說,我們要有一種高效地讀取寫入到System.out和System.err所有內容的方法。Java的管道流PipedInputStream和PipedOutputStream是一個非常有效的工具。
寫入到PipedOutputStream輸出流的數據可以從對應的PipedInputStream輸入流讀取。Java的管道流極大地方便了我們截取控制台輸出。Listing 1顯示了一種非常簡單的截取控制台輸出方案。
【Listing 1:用管道流截取控制台輸出】
[java] view plaincopy
PipedInputStream pipedIS = new PipedInputStream();
PipedOutputStream pipedOS = new PipedOutputStream();
try {
pipedOS.connect(pipedIS);
}
catch(IOException e) {
System.err.println(“連接失敗”);
System.exit(1);
}
PrintStream ps = new PrintStream(pipedOS);
System.setOut(ps);
System.setErr(ps);
原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-hant/n/155414.html