编写一个利用管道流,实现线程之间的通信,实现文件传输功能Java程序

如何在学习Java过程中实现线程之间的通信~

在java中,每个对象都有两个池,锁池(monitor)和等待池(waitset),每个对象又都有wait、notify、notifyAll方法,使用它们可以实现线程之间的通信,只是平时用的较少.
wait(): 使当前线程处于等待状态,直到另外的线程调用notify或notifyAll将它唤醒notify(): 唤醒该对象监听的其中一个线程(规则取决于JVM厂商,FILO,FIFO,随机…)notifyAll(): 唤醒该对象监听的所有线程锁池: 假设T1线程已经拥有了某个对象(注意:不是类)的锁,而其它的线程想要调用该对象的synchronized方法(或者synchronized块),由于这些线程在进入对象的synchronized方法之前都需要先获得该对象的锁的拥有权,但是该对象的锁目前正被T1线程拥有,所以这些线程就进入了该对象的锁池中.
等待池: 假设T1线程调用了某个对象的wait()方法,T1线程就会释放该对象的锁(因为wait()方法必须出现在synchronized中,这样自然在执行wait()方法之前T1线程就已经拥有了该对象的锁),同时T1线程进入到了该对象的等待池中.如果有其它线程调用了相同对象的notifyAll()方法,那么处于该对象的等待池中的线程就会全部进入该对象的锁池中,从新争夺锁的拥有权.如果另外的一个线程调用了相同对象的notify()方法,那么仅仅有一个处于该对象的等待池中的线程(随机)会进入该对象的锁池.
java实现线程间通信的四种方式
1、synchronized同步:这种方式,本质上就是“共享内存”式的通信。多个线程需要访问同一个共享变量,谁拿到了锁(获得了访问权限),谁就可以执行。
2、while轮询:其实就是多线程同时执行,会牺牲部分CPU性能。
3、wait/notify机制
4、管道通信:管道流主要用来实现两个线程之间的二进制数据的传播

一起学习,管道流满搞的,用着比socket的stream麻烦
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.*;
import java.nio.channels.*;
import java.nio.*;
import java.util.*;
import java.nio.charset.*;
public class TCP extends Thread{
private SocketChannel channel;
private ServerSocket serverSocket;
private ServerSocketChannel serverSocketChannel;
private ByteBuffer readBuffer;
private ByteBuffer sendBuffer;
private Boolean isAccept=false;
private boolean isConnect=false;
private Thread accept;
private Thread connect;
/** Creates a new instance of TCP */
public TCP(int port,String addr) {
try {
readBuffer=ByteBuffer.allocate(1024);
serverSocketChannel=ServerSocketChannel.open();
serverSocket=serverSocketChannel.socket();
serverSocket.setReuseAddress(true);
serverSocket.bind(new InetSocketAddress(port));
channel=SocketChannel.open();
channel.connect(new InetSocketAddress(InetAddress.getByName(addr),port));
accept=new Thread(){
public void run(){
Selector selector;
try {
selector=Selector.open();
serverSocketChannel.configureBlocking(false);
serverSocketChannel.register(selector,SelectionKey.OP_ACCEPT);
isAccept=false;
selectors(selector);
} catch (ClosedChannelException ex) {
ex.printStackTrace();
} catch (IOException ex) {
ex.printStackTrace();
}
}
};
connect=new Thread(){
public void run(){
try{
Selector selector;
selector=Selector.open();
channel.configureBlocking(false);
channel.register(selector,SelectionKey.OP_WRITE|SelectionKey.OP_READ);
isConnect=false;
selectors(selector);
}catch (Exception ex){
ex.printStackTrace();
}
}
};
} catch (IOException ex) {
ex.printStackTrace();
System.out.println("d1");
}catch(Exception ex){
System.out.println("d2");
}
}
private void service(){
if(isConnect){
connect.start();
}
if(isAccept){
accept.start();
}
}
private void selectors(Selector selector){
try {
while (selector.select()>0){
Set readyKeys=selector.selectedKeys();
Iterator it=readyKeys.iterator();
while(it.hasNext()){
SelectionKey key=null;
key=it.next();
it.remove();
if(key.isAcceptable()){
//System.out.println("isAcceptable");
ServerSocketChannel ssc=(ServerSocketChannel)key.channel();
SocketChannel socketChannel=ssc.accept();
socketChannel.configureBlocking(false);
socketChannel.register(selector,SelectionKey.OP_READ|SelectionKey.OP_WRITE);
}
if(key.isReadable()){
synchronized(readBuffer){
// System.out.println("isReadable");
ByteBuffer buffer=ByteBuffer.allocate(1024);
SocketChannel socketChannel=(SocketChannel)key.channel();
socketChannel.read(buffer);
readBuffer=buffer;
}
}
if(key.isWritable()){
synchronized(sendBuffer){
// System.out.println("isWritable");
SocketChannel channel=(SocketChannel)key.channel();
if(sendBuffer!=null)
channel.write(sendBuffer);
}
}

}
try {
sleep(1);
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
} catch (ClosedChannelException ex) {
ex.printStackTrace();
} catch (IOException ex) {
ex.printStackTrace();
}
}


public void send(ByteBuffer buff){
this.sendBuffer=buff;
}
public ByteBuffer get(){
return readBuffer;
}
public void accpet(){
isAccept=true;
}
public void connect(){
isConnect=true;
}
public void run(){
while (true){
service();
}
}
}

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;
import java.io.PrintWriter;
public class Day10A {
private BufferedReader br;// 字符效率读取流
private BufferedWriter bw;// 字符效率写出流
private PipedInputStream pis;// 管道读取流
private PipedOutputStream pos;// 管道输出流,
private byte[] readBytes;// 读取缓冲区
private byte[] writeBytes;// 写出缓冲区
private String path = "C:\\Users\\Administrator\\Desktop";
private File file = null;
private FileOutputStream fos = null;

Day10A() {
writeBytes = new byte[1024];
file = new File(path, "测试.txt");
try {
if (!file.exists()) {
file.createNewFile();
fos = new FileOutputStream(file);
} else {
fos = new FileOutputStream(file, true);
}
br = new BufferedReader(new InputStreamReader(System.in));
bw = new BufferedWriter(new PrintWriter(fos));
pis = new PipedInputStream();
pos = new PipedOutputStream();
pis.connect(pos);
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
Day10A d = new Day10A();
d.readFunction();
d.writerFunction();
}
private void readFunction() {
new Thread(new Runnable() {
public void run() {
while (true) {
try {
for (String str = br.readLine();!str.contentEquals("over"); str = br.readLine()) {
readBytes = str.getBytes();
pos.write(readBytes);
}
} catch (Exception e) {
}
break;
}
try {
pos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
}
private void writerFunction() {
new Thread(new Runnable() {
@Override
public void run() {
try {
String str = "";
for (int len = pis.read(writeBytes); len != -1; len = pis.read(writeBytes)) {
str = new String(writeBytes, 0, len);
bw.write(str + "
");
bw.flush();
}
} catch (Exception e) {
}
}
}).start();
}
}



c++ 如何在构造函数中启动一个线程,从命名管道读取数据?
答:线程使用中最大的问题就是同步问题,一般使用生产着消费者模型进行处理,使用条件变量pthread_cond_t,pthread_mutex,pthread_cond_wait来实现。2、例程(创建5个线程):include <pthread.h>#include <stdlib.h>void* work_thread(void* arg){//线程执行体return 0;}int main(int argc,char* argv[...

C语言中 怎么实现双线程 或者 父子线程啊
答:首先指出,线程与线程之间,是并列关系,不会存在"父子线程"的概念.在Windows平台下,CreateThread函数包含在 Windows.h 文件内,包含此文件即可正常使用.以下为CreateThread函数的声明:HANDLE CreateThread(LPSECURITY_ATTRIBUTES lpThreadAttributes,//指向安全性属性描述结构体的 //指针,通常可以忽略的.SIZE_T dw...

JAVA中为实现多线程之间的通信,需要使用下列哪种流才合适
答:D,管道流,此流一般用于多线程

java实时数据字符串对象怎么在线程间传递
答:实际上并不是那么简单的用管道流实现的,当然如果你能保证同步的话可以直接用管道 线程这个东西本来就是共享进程资源的,所以没有特殊的传送机制,直接使用就行了。在java中就是直接使用对象里的字段。你这个就是一个生产者消费者模型,可以用一个队列实现,接受socket作为生产者往一个队列中存字符串,...

java操作流的方法
答:六、管道PipedInputStream/PipedOutputStream类:当需要在两个线程中读写数据的时候,由于线程的并发执行,读写的同步问题可能会发生困难,这时候可以使用管道,管道事实上是一个队列。管道是由系统维护的一个缓冲区,当然程序员也可以自己直接指定该缓冲区的大小(只需要设置管道流类中的PIPE_SIZE属性的值)。当生产者生产出...

JAVA问题简单的很,菜鸟送分,在线等
答:DataInputStream和DataOutputStream,过滤流,需要使用已经存在的节点流来构造,提供了读写Java中的基本数据类型的功能。PipedInputStream和PipedOutputStream,管道流,用于线程间的通信。一个线程的PipedInputStream对象从另一个线程的PipedOutputStream对象读取输入。要使管道流有用,必须同时构造管道输入流和管道...

java管道流有什么用呢??
答:管道流只是帮你把得到10,的字节编程你需要的字符而已,等等类似的功能 管道流帮你减少一个自己转的过程,还是比较方便

6 请简述java io中stream流和read流的区别,并分别列举2个常用的strea...
答:method --- read() 从当前输入流中读取一字节数据。 read(byte[]) 将当前输入流中 b.length 个字节数据读到一个字节数组中。 read(byte[], int, int) 将输入流中 len 个字节数据读入一个字节数组中。 1.4 PipedInputStream :实现了 pipe 的概念,主要在线程中使用 . 管道输入流是指一个通讯管道的接收端。

java 进程间通讯的有几种方法?
答:而在java中我们实现多线程间通信则主要采用"共享变量"和"管道流"这两种方法 方法一 通过访问共享变量的方式(注:需要处理同步问题)方法二 通过管道流 其中方法一有两种实现方法,即方法一a)通过内部类实现线程的共享变量代码如下:public class Innersharethread {public static void main(String[] args) {...

Java中的I/O流的基本知识
答:与RandomAccessFile类所不同的是,FileInputStream和FileOutputStream类中提供的文件处理方式是文件中数据流的顺序读写,而不是利用文件指针进行定位的随机读写 10、Java中的PipedInputStream和PipedOutputStream类提供了利用管道方式进行数据输入输出管理。管道流用来将一个程序或者线程的输出连接到另外一个程序或...

IT评价网,数码产品家用电器电子设备等点评来自于网友使用感受交流,不对其内容作任何保证

联系反馈
Copyright© IT评价网