PipeInputStream和PipeOutputStream是同步还是异步?

时间:2013-04-11 15:24:42

标签: java multithreading asynchronous io blocking

我正在读一本Java书,我发现了一个似乎不正确的句子:

  

阅读时,如果没有可用数据,该主题将阻止,直到新数据可用。请注意,这是典型的异步行为,线程通过通道(管道)进行通信。

为什么作者将操作称为“异步”?不应该异步意味着线程在收到新数据之前不会被阻塞吗?

稍后编辑:

我运行此代码并从输出中看起来行为是异步的。

以下是输出的一部分:http://ideone.com/qijn0B

代码如下。 你觉得怎么样?

import java.io.*;
import java.util.logging.Level;
import java.util.logging.Logger;

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/**
 *
 * @author dragos
 */

class Consumator extends Thread{
    DataInputStream in;

    public Consumator(DataInputStream in){
        this.in = in;
    }

    public void run(){
        int value = -1;
        for(int i=0;i<=1000;i++){
            try {
                value = in.readInt();
            } catch (IOException ex) {
                Logger.getLogger(Consumator.class.getName()).log(Level.SEVERE, null, ex);
            }
            System.out.println("Consumator received: "+ value);
        }
    }
}

class Producator extends Thread{
    DataOutputStream out;

    public Producator(DataOutputStream out){
        this.out = out;
    }

    public void run(){

        for(int i=0;i<=1000;i++){
            try {
                out.writeInt(i);
            } catch (IOException ex) {
                Logger.getLogger(Producator.class.getName()).log(Level.SEVERE, null, ex);
            }
            System.out.println("Producator wrote: "+i);
        }
    }
}

public class TestPipes {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) throws IOException {
        PipedInputStream pipeIn = new PipedInputStream();
        PipedOutputStream pipeOut = new PipedOutputStream(pipeIn);

        DataInputStream in = new DataInputStream(pipeIn);
        DataOutputStream out = new DataOutputStream(pipeOut);

        Consumator c = new Consumator(in);
        Producator p = new Producator(out);

        p.start();
        c.start();

    }

}

2 个答案:

答案 0 :(得分:1)

  

为什么作者将操作称为“异步”?不应该异步意味着线程在收到新数据之前不会被阻塞吗?

这是不正确的,或者作者正在讨论消费者线程如何阻止,但生产者线程仍然会运行。至少这个措辞肯定令人困惑。

在任何情况下,PipeInputStreamPipeOutputStream流共享内部缓冲区,否则为“同步”。如果缓冲区已满,则编写器将阻塞,如果缓冲区为空,则读取器将阻塞。

答案 1 :(得分:0)

是的,您没有显示全文。如果作者说生产者没有被阻止,那么它是异步的。消费总是阻碍。 (好的,有时您可以检查答案的可用性,但同步/异步是根据发件人的行为来区分的)。当缓冲区长度为0时它将被阻塞,然后写入器将始终阻塞并发生同步。因此,我们可以说阻塞/非阻塞(同步/异步)是通道的一个特性。