日期:2014-05-20  浏览次数:20776 次

用PipedInputStream/PipedOutputStream进行线程间通讯会有延迟?
请看下面的代码:
Java code

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;
import java.io.PrintStream;

public class Expriment
{
   public Expriment()
   {
   }

   /**
    * Launch the application.
    */
   public static void main(String[] args)
   {
      try
      {
         PipedInputStream pis = new PipedInputStream(1024);
         PipedOutputStream pos = new PipedOutputStream(pis);
         ReadThread rt = new ReadThread(pis);
         WriteThread wt = new WriteThread(pos);
         wt.start();
         rt.start();
         Thread.sleep(10000);
         wt.interrupt();
         rt.interrupt();
      } catch (IOException e)
      {
         e.printStackTrace();
      } catch (InterruptedException e)
      {
         e.printStackTrace();
      }
   }

}

class WriteThread extends Thread
{
   public WriteThread(OutputStream outputStream)
   {
      this.outputStream = outputStream;
   }

   @Override
   public void run()
   {
      int count = 0;
      do
      {
         count++;
         try
         {
            outputStream.write(new String(count + ": Hello, world ! I'm a write thread.\n").getBytes());
            sleep(250);
         } catch (IOException e)
         {
            e.printStackTrace();
            break;
         } catch (InterruptedException e)
         {
            e.printStackTrace();
            break;
         }
      } while(!interrupted());
   }

   private OutputStream outputStream;
}

class ReadThread extends Thread
{
   public ReadThread(InputStream inputStream)
   {
      this.inputStream = inputStream;
   }

   @Override
   public void run()
   {
      byte[] buffer = new byte[1024];
      do
      {
         try
         {
            int readCount = inputStream.read(buffer, 0, 16);
            if (readCount > 0)
            {
               System.out.print(new String(buffer, 0, readCount));
            }
         } catch (IOException e)
         {
            e.printStackTrace();
            break;
         }
      } while(!interrupted());
   }

   private InputStream inputStream;
}


ReadThread和WriteThread分别通过PipedInputStream和PipedOutputThread建立了数据交换通道。代码运行之后,WriteThread写入的数据的确可以被ReadThread读出,但是却并不是实时地被读出,而是被延迟了固定的1秒钟。运行之后就会发现控制台上每秒钟才显示一次信息,而每次显示的是WriteThread四次输出的信息。

这究竟是怎么回事?为什么WriteThread写入管道输出流的数据,ReadThread却是时隔1秒钟才能读出?

------解决方案--------------------
一般来说,OutputStream类的,都会有写入缓冲机制。如果你很着急,就在outputStream.write 后面写:outputStream.flush();
------解决方案--------------------
线程间通讯通常使用共享内存的办法 最快 最方便