while((c=(char)in.read())!=-1)
这句的条件错误
虽然文档上说流结束时返回-1,也许是文档没有更新,当事实上当所有数据都读完时in.read()将阻塞!除非调用in.close()否则while将无法停止。

解决方案 »

  1.   

    sorry,说错了,in.read()在没有数据可读时将阻塞直到调用in.close()返回-1
      

  2.   

    楼上的朋友,我觉得你说的这种情况可能性不大。因为我是发一个数据(一个String)后,再让Thread2.notify,而PipedReader和PipedWriter之间的关系是生产和消费的关系。int read()将返回一个int型,如果没有数据会读到一个-1的返回值,应该是不存在没有数据更新而导致阻塞的情况。另如果while((c=(char)in.read())!=-1)有错,应该如何写这个条语句。
      

  3.   

    不过ark13(秋分) 说的情况和我碰到的情况还是有相似之处的。
    String m="";
    while((c=(char)in.read())!=-1){
    m=m+c;
    System.out.print(m);

    System.out.print(m);每一次都可以打印出m的值,我每次从thread1线程的out写一个String,thread2的m就会打印到该String的值,只不过不能跳到循环外打印m。如果真的是int read()读完数据后不能返回-1,我的程序应该如何解决?
      

  4.   

    之所以阻塞,是因为你out没有close(),只有out.close();了,in.read()最终才能读到-1//////////////////////////////////////
    Thread1:
    PipedWriter out=new PipedWriter();
    String m="abcd";
    out.write(m.toCharArray());
    out.close(); //加入close() 就可以了Thread2:
    PipedReader in=new PipedReader(out);
    char c;
    while((c=(char)in.read())!=-1){
    m=m+c;
    System.out.print(m);
    }
    System.out.print(m);//这句死活都不执行,这是为什么原因?==>因为out并没有close(),读不到-1 ,so wait until at least one byte of input is available.另外主线程要注意,两个线程都start后,main有可能很快就中止了,并不能保证thead2能把所有的thread1输出的字符全部读出,所以如果要看效果的话,可以再main中加入thread2.join(),让主线程等待thread2把流中的字符全部读出,然后再中止。
    当然,join方法已经不推荐使用了,此处仅为测试,如果要写健壮的代码,可以考虑其他比较优化的结构。
      

  5.   

    NetSniffer(扑克)谢谢你的解释,我明白了。不过如果我的需求是thread1是在读取键盘上的输入,读一个就给thread2发一个输入,如果我close()了我的pipedwriter,我要再发数据过来起不是要再建一个pipedwriter?
      

  6.   

    由于我的程序要求反复读取system.in的内容,如果必须在关闭pipedwriter后才能接收输入,那么必须反复的新建和关闭pipedwriter,这样很不合理,有没有更好的办法?
      

  7.   

    import java.io.*;class Demo
       extends Thread
    {
       public Demo()
       {   }   public static void main(String[] args) throws Exception
       {
          Demo demo = new Demo();
          demo.start();
          int count = 0;
          while(true)
          {
             if(demo.mNotify.available()==0)
             {
                //键盘没有输入,作些其它事情...
                Thread.sleep(500);
                if(++count > 20)
                {
                   System.out.println("你个大菠萝,我砍翻你!");
                   count=0;
                }
             }
             else
             {
                demo.mNotify.read();
                if (demo.mCommand.compareTo("QUIT") == 0 ||
                    demo.mCommand.compareTo("quit") == 0)
                {
                   System.out.println("回家睡觉");
                   return;
                }            System.out.println("没事别烦我,忙着呢...");
             }
          }
       }   String mCommand;
       final PipedInputStream mNotify=new PipedInputStream();
          public void run()
       {
          try
          {
             BufferedReader read = new BufferedReader(new InputStreamReader(
                System.in));
             PipedOutputStream notify=new PipedOutputStream(mNotify);
             while (true)
             {
                mCommand = read.readLine();
                notify.write(0);
                notify.flush();
                if (mCommand.compareTo("QUIT") == 0 ||
                    mCommand.compareTo("quit") == 0)
                {
                   notify.close();
                   break;
                }
             }
          }
          catch (Exception e)
          {
          }
       }}
      

  8.   

    用一个临界区:
    用一个线程(生产者)在一个死循环当中不断读取输入.当读到输入则唤醒消费者,因为IO方法自动阻塞,所以不必令其睡觉.(不消耗系统资源)
    另一个线程(消费者)在一个死循环当中不断输出结果.如果没有数据则阻塞,被唤醒之后处理数据,然后阻塞(循环当中)这两个死循环都依赖一个变量 :
    boolean stop = false;while (!stop) {
       ....
    }当程序要退出的时候,主线程设置 stop = true, 之后两个线程安全退出.代码太罗嗦,就不贴了.
      

  9.   

    windExtendsRikki(风) 你好,你所说的模型是一种高性能并发处理的模型,它在多个生产者对多个消费者并且数据间没有紧密的逻辑关系时使用。
    你所描述的这种情况,只有一个消费者,一个生产者,并且消费者在生产者阻塞时也跟着阻塞,放两个线程大部分时间在那阻塞这有必要吗?键盘是低速设备,还不如就一个主线程直接接收键盘输入,得到后自己处理效果是一样的。现在楼主的需求是:有两个(或更多)的生产者的数据需要处理,一个是键盘输入的<命令>另一个是与<命令>在逻辑上紧密相关的<数据>。
    在键盘输入阻塞时需要处理<数据>,因此需要一个独立的线程监控键盘输入,另一个线程处理<数据>,因为<命令>与<数据>在逻辑顺序上紧密相关用第三个线程处理将会使问题复杂化,因此处理数据的线程不想阻塞并不时的回来看看键盘是否输入了命令以决定下一步处理。举一个实际的例子:简单的交换机终端,接收用户输入的命令,(处理后或直接)发给交换机,然后接收交换机报告,程序在接收交换机的报告时必须同时监控用户输入的命令,但是否处理命令如何处理要看交换机的应答报告,成功、失败、等待输入参数等,因为这个交换机是半双工的因此必须确认交换机不在吐数据时才能发命令否则将造成一次交互失败。