JAVA NIO中Pipe的通信能力

   我正在写一个Nio的程序,要求是一个进行为主进程,通过Chanell以及Selecotr进行循环,并从Socket取得数据后
做为生产者送入Pipe,另个一个ThreadPool进行做为消费者从Pipe中取数据,但是发现了一个问题,有时候生产者
生产数据过快时,可能部分数据会丢失。那么Pipe到底是一个什么样的通道呢,它是的缓冲区有多大呢?
我写了一个程序进行测试
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.Pipe;

public class B
{
    public static int num = 5000;
    static Pipe pipe;
    static boolean flag = false;
    static
    {
        try
        {
            pipe = Pipe.open();
            pipe.sink().configureBlocking(true);
            pipe.source().configureBlocking(true);
        } catch (IOException e)
        {
            e.printStackTrace();
        }
    }

    public static class B1 implements Runnable
    {
        ByteBuffer buf;

        @Override
        public void run()
        {
            System.out.println("Start create.");
            for (int i = 0; i < num; i++)
            {
                String s = String.format("%08d", i);
                buf = ByteBuffer.wrap(s.getBytes());
                if (checkOut(i))
                    System.out.println(String.format("Create %d", i));
                try
                {
                    pipe.sink().write(buf);
                } catch (IOException e)
                {
                    e.printStackTrace();
                }
            }
            System.out.println("Create end.");
            flag = true;
        }
    }

    public static boolean checkOut(int i)
    {
        boolean outflag = false;
        if (i <= 3000)
        {
            if ((i % 500) == 0) outflag = true;
        } else if (i < 4000)
        {
            if ((i % 100) == 0) outflag = true;
        } else if (i < 4100)
        {
            if ((i % 10) == 0) outflag = true;
        } else
        {
            outflag = true;
        }
        return outflag;
    }

    public static class B2 implements Runnable
    {
        @Override
        public void run()
        {
            while (!flag)
            {
                Thread.yield();
            }
            /*
            try
            {
                Thread.sleep(100);
            } catch (InterruptedException e1)
            {
                e1.printStackTrace();
            }*/
            System.out.println("Start receive.");
            ByteBuffer bb = ByteBuffer.allocateDirect(8);
            byte[] bytebuf = new byte[8];
            for (int i = 0; i < num; i++)
            {
                if (checkOut(i))
                    System.out.println(String.format("Receive %d", i));
                try
                {
                    bb.clear();
                    pipe.source().read(bb);
                } catch (IOException e)
                {
                    e.printStackTrace();
                }
                bb.flip();
                bb.get(bytebuf, 0, 8);
                String s = new String(bytebuf);
                if (null == s)
                    System.out.println(String.format("ERR:%d", i));
                else
                {
                    String s1 = String.format("%08d", i);
                    if (s1.compareTo(s) != 0)
                        System.out
                                .println(String.format("ERR:%d /"%s/"", i, s));
                }
            }
            System.out.println("receive end.");
        }

    }

    public static void main(String[] argv)
    {
        new Thread(new B1()).start();
        new Thread(new B2()).start();
    }
}


运行结果:
Start create.
Create 0
Create 500
...
Create 4125
Create 4126
Create 4127
Create 4128
Create 4129
根据结果,可以判定,在阻塞模式下,Pipe的写入端当Pipe的缓冲区满的时候,后出现阻塞。
写入输出缓会在第4129处停下来,因此,Pipe的缓冲区有33024个字节,相当于32K+256个字节。

考虑到这样的结果,我在主线程中在Socket写入Pipe时,采用了非阻塞模式,并加入了相关是否
正确写入的判断,系统就运行正常了。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值