Ste*_*wig 49 java concurrency design-patterns pipe
我最近发现了这个成语,我想知道是否有我遗失的东西.我从来没有见过它.我在野外工作的几乎所有Java代码都倾向于将数据压入字符串或缓冲区,而不是像这个例子(例如使用HttpClient和XML API):
final LSOutput output; // XML stuff initialized elsewhere
final LSSerializer serializer;
final Document doc;
// ...
PostMethod post; // HttpClient post request
final PipedOutputStream source = new PipedOutputStream();
PipedInputStream sink = new PipedInputStream(source);
// ...
executor.execute(new Runnable() {
public void run() {
output.setByteStream(source);
serializer.write(doc, output);
try {
source.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}});
post.setRequestEntity(new InputStreamRequestEntity(sink));
int status = httpClient.executeMethod(post);
Run Code Online (Sandbox Code Playgroud)
该代码使用Unix管道样式技术来防止XML数据的多个副本保留在内存中.它使用HTTP Post输出流和DOM Load/Save API将XML Document序列化为HTTP请求的内容.至于我可以告诉它最大限度地减少用很少的额外代码使用的内存(只是几行了Runnable,PipedInputStream和PipedOutputStream).
那么,这个成语有什么问题?如果这个成语没有错,为什么我没有看到它?
编辑:澄清PipedInputStream并PipedOutputStream替换到处显示的样板缓冲区副本,它们还允许您在写出已处理数据的同时处理传入数据.他们不使用OS管道.
在你的例子中,你创建了两个线程来完成一个可以完成的工作.并将I/O延迟引入混合中.
你有更好的例子吗?或者我只是回答你的问题.
将一些评论(至少我对它们的看法)提取到主要回复中:
在特定示例中,管道流允许使用由HttpClient提供的现有RequestEntity实现类.我认为更好的解决方案是创建一个新的实现类,如下所示,因为该示例最终是一个顺序操作,无法从并发实现的复杂性和开销中受益.虽然我将RequestEntity显示为匿名类,但可重用性表明它应该是一流的类.
post.setRequestEntity(new RequestEntity()
{
public long getContentLength()
{
return 0-1;
}
public String getContentType()
{
return "text/xml";
}
public boolean isRepeatable()
{
return false;
}
public void writeRequest(OutputStream out) throws IOException
{
output.setByteStream(out);
serializer.write(doc, output);
}
});
Run Code Online (Sandbox Code Playgroud)
我最近也发现了PipedInputStream/PipedOutputStream类.
我正在开发一个Eclipse插件,需要通过SSH在远程服务器上执行命令.我正在使用JSch和Channel API从输入流读取并写入输出流.但我需要通过输入流提供命令并从输出流中读取响应.这是PipedInput/OutputStream的用武之地.
import java.io.PipedInputStream;
import java.io.PipedOutputStream;
import com.jcraft.jsch.Channel;
Channel channel;
PipedInputStream channelInputStream = new PipedInputStream();
PipedOutputStream channelOutputStream = new PipedOutputStream();
channel.setInputStream(new PipedInputStream(this.channelOutputStream));
channel.setOutputStream(new PipedOutputStream(this.channelInputStream));
channel.connect();
// Write to channelInputStream
// Read from channelInputStream
channel.disconnect();
Run Code Online (Sandbox Code Playgroud)