package com.test.socket;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.channels.Pipe;
import java.nio.channels.Pipe.SinkChannel;
import java.nio.channels.Pipe.SourceChannel;
import java.nio.charset.Charset;
public class PipeTestMain {
private static final byte end = '\n';
/**
* @param args
*/
public static void main(String[] args) {
try{
Pipe pipe = Pipe.open();
Thread c1 = new Consumer(pipe.source());
c1.start();
Thread c2 = new Consumer(pipe.source());
c2.start();
Thread c3 = new Consumer(pipe.source());
c3.start();
Thread productor = new Productor(pipe.sink());
productor.start();
Thread.sleep(2000);
}catch(Exception e){
e.printStackTrace();
}
}
static class Consumer extends Thread{
static final Object lock = new Object();//Read a packet
SourceChannel channel;
Consumer(SourceChannel channel){
this.channel = channel;
}
@Override
public void run(){
try{
Charset charset = Charset.defaultCharset();
ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
while(channel.isOpen()){
synchronized (lock) {
while(channel.read(byteBuffer) != -1){
int current = byteBuffer.position() - 1;
byte last = byteBuffer.get(current);
if(last == end){
byteBuffer.position(current);//remove the '\n'
break;
}
}
}
byteBuffer.flip();
CharBuffer charBuffer = charset.decode(byteBuffer);
System.out.println(Thread.currentThread().getId() + ",I get something like this:'" + charBuffer.toString() + "'");
byteBuffer.clear();
}
}catch(Exception e){
e.printStackTrace();
}finally{
try{
channel.close();
}catch(Exception ex){
ex.printStackTrace();
}
}
}
}
static class Productor extends Thread{
static final Object lock = new Object();//Read a packet
SinkChannel channel;
Productor(SinkChannel channel){
this.channel = channel;
}
@Override
public void run(){
try{
Charset charset = Charset.defaultCharset();
while(channel.isOpen()){
///only for write
String data = "System-time:" + System.currentTimeMillis();
ByteBuffer byteBuffer = charset.encode(data);
appendEnd(byteBuffer);
int i = 0;
synchronized (lock) {
while(byteBuffer.hasRemaining()){
int count = channel.write(byteBuffer);
if(count == 0)
i++;
if(i > 100){
throw new RuntimeException("Pipe has been blocked so long,please check!");
}
}
}
Thread.sleep(1000);
}
}catch(Exception e){
e.printStackTrace();
}finally{
try{
channel.close();
}catch(Exception ex){
ex.printStackTrace();
}
}
}
}
/**
* happen-before: buffer must be flip()
* @param byteBuffer
* @return
*/
static ByteBuffer appendEnd(ByteBuffer byteBuffer){
int limit = byteBuffer.limit();
if(limit == 0 ){
throw new RuntimeException("Array overflow error.please keep right position.");
}
byteBuffer.clear();
byteBuffer.position(limit);
byteBuffer.put(end);
byteBuffer.flip();
return byteBuffer;
}
}