Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java PipedInputStream和TeeOutputStream在未读取时冻结应用程序?_Java_Multithreading_Io_Freeze - Fatal编程技术网

Java PipedInputStream和TeeOutputStream在未读取时冻结应用程序?

Java PipedInputStream和TeeOutputStream在未读取时冻结应用程序?,java,multithreading,io,freeze,Java,Multithreading,Io,Freeze,PipedInputStream与TeeOutputStream一起在未读取时冻结应用程序 我指的是这个org.apache.commons.io.output.TeeOutputStream。为了便于测试,我添加了它的一个简单变体作为内部类(MyTeeOutputStream),这样就不必获取依赖关系 你知道为什么会发生这种情况,以及我如何解决它吗 代码 我制作了一个JUnit5测试用例供大家试用: @测试 void testSplittingOutput()引发IOException、Int

PipedInputStream与TeeOutputStream一起在未读取时冻结应用程序

我指的是这个
org.apache.commons.io.output.TeeOutputStream
。为了便于测试,我添加了它的一个简单变体作为内部类(
MyTeeOutputStream
),这样就不必获取依赖关系

你知道为什么会发生这种情况,以及我如何解决它吗

代码 我制作了一个JUnit5测试用例供大家试用:

@测试
void testSplittingOutput()引发IOException、InterruptedException{
PipedInputStream pipedInput=新的PipedInputStream();
OutputStream pipedOutput=新的PipedOutStream(pipedInput);
//TeeOutputStream teeOutput=新的TeeOutputStream(System.out,pipedOutput);
MyTeeOutputStream teeOutput=新的MyTeeOutputStream(System.out,pipedOutput);
PrintStream out=新的PrintStream(输出);
预期最终整数PrintedLinesCount=1000;
AtomicInteger ActualPrintedLineScont=新的AtomicInteger();
线程t1=新线程(()->{//用于向OUT写入数据的线程
试一试{
对于(int i=0;i{//用于从中读取数据的线程
BufferedReader reader=新的BufferedReader(新的InputStreamReader(pipedInput));
StringBuilder=新的StringBuilder();
试一试{
while(true){
builder.append(reader.readLine());
}
}捕获(IOE异常){
//e、 printStackTrace();//忽略
System.out.println(生成器);
}
});
t1.start();
//t2.start();//如果我们不读取Thread2中的PipedInputStream,我们只打印94行而不是1000行!?
对于(inti=0;i<30;i++){//30秒,等待线程完成的最大时间
sleep(1000);//这样做是因为Junit不支持多线程的东西
}
assertEquals(ExpectedPrintedLineScont、ActualPrintedLineScont.get()+1);
}
最终类MyTeeOutputStream扩展OutputStream{
私有最终输出流输出;
专用最终输出流三通;
公共MyTeeOutputStream(OutputStream out,OutputStream tee){
if(out==null)
抛出新的NullPointerException();
else if(tee==null)
抛出新的NullPointerException();
this.out=out;
this.tee=tee;
}
@凌驾
公共无效写入(int b)引发IOException{
写出(b);
写(b);
}
@凌驾
公共无效写入(字节[]b)引发IOException{
写出(b);
写(b);
}
@凌驾
公共无效写入(字节[]b,int off,int len)引发IOException{
注销(b,注销,len);
T.注销(b、注销、len);
}
@凌驾
public void flush()引发IOException{
out.flush();
T.齐平();
}
@凌驾
public void close()引发IOException{
试一试{
out.close();
}最后{
tee.close();
}
}
}
结果 如您所见,它无法打印所有行(1000),并在(94)处停止:

你好!0
你好1.
你好2.
你好3.
你好4.
你好5.
你好6.
你好7.
你好8.
你好9
你好10
你好11
你好12
你好13
你好14
你好15
你好16
你好17
你好18
你好19
你好20
你好21
你好22
你好23
你好24
你好25
你好26
你好27
你好28
你好29
你好30
你好31
你好32
你好33
你好34
你好35
你好36
你好37
你好38
你好39
你好40
你好41
你好42
你好43
你好44
你好45
你好46
你好47
你好48
你好49
你好50
你好51
你好52
你好53
你好54
你好55
你好56
你好57
你好58
你好59
你好60
你好61
你好62
你好63
你好64
你好65
你好66
你好67
你好68
你好69
你好70
你好71
你好72
你好73
你好74
你好75
你好76
你好77
你好78
你好79
你好80
你好81
你好82
你好83
你好84
你好85
你好86
你好87
你好88
你好89
你好90
你好91
你好92
你好93
你好94
org.opentest4j.AssertionFailedError:
预计:1 000
实际:94
细节 我为什么要这样做?
我想复制System.out并从中“读取”(通过PipedInputStream),然后将该数据发送到我网站的http控制台。

A
PipedInputStream
默认情况下只有1024个缓冲区,因此,如果您添加到PipedOutputStream而不在其他线程中读取,它将阻止写入,直到缓冲区清空。这就是为什么它停在
Hello的第94行!XX\r\n
。1024除以11意味着93条完整的输出线存储在
管道输入中,System.out适用于第94条线,但管道输入上的阻塞会阻止添加更多的线。

最适合我的解决方案:

非阻塞PipedInputStream
公共类非阻塞PipedInputStream扩展PipedInputStream{
公共接口WriteLineEvent{
无效执行事件(L);
}
/**
*将操作添加到此列表,这些操作将在写入行后运行。
*包含作为参数的行。
*/
public List actions sonWriteLineEvent=新建CopyOnWriteArrayList();
/**
*
*启动一个新的{@link Thread},该线程读取{@link PipedInputStream}
*并在每次写入整行时激发一个事件。
*要侦听这些事件,请将应该运行的操作添加到{@link#actionsOnWriteLineEvent}列表中。
Hello! 0
Hello! 1
Hello! 2
Hello! 3
Hello! 4
Hello! 5
Hello! 6
Hello! 7
Hello! 8
Hello! 9
Hello! 10
Hello! 11
Hello! 12
Hello! 13
Hello! 14
Hello! 15
Hello! 16
Hello! 17
Hello! 18
Hello! 19
Hello! 20
Hello! 21
Hello! 22
Hello! 23
Hello! 24
Hello! 25
Hello! 26
Hello! 27
Hello! 28
Hello! 29
Hello! 30
Hello! 31
Hello! 32
Hello! 33
Hello! 34
Hello! 35
Hello! 36
Hello! 37
Hello! 38
Hello! 39
Hello! 40
Hello! 41
Hello! 42
Hello! 43
Hello! 44
Hello! 45
Hello! 46
Hello! 47
Hello! 48
Hello! 49
Hello! 50
Hello! 51
Hello! 52
Hello! 53
Hello! 54
Hello! 55
Hello! 56
Hello! 57
Hello! 58
Hello! 59
Hello! 60
Hello! 61
Hello! 62
Hello! 63
Hello! 64
Hello! 65
Hello! 66
Hello! 67
Hello! 68
Hello! 69
Hello! 70
Hello! 71
Hello! 72
Hello! 73
Hello! 74
Hello! 75
Hello! 76
Hello! 77
Hello! 78
Hello! 79
Hello! 80
Hello! 81
Hello! 82
Hello! 83
Hello! 84
Hello! 85
Hello! 86
Hello! 87
Hello! 88
Hello! 89
Hello! 90
Hello! 91
Hello! 92
Hello! 93
Hello! 94
org.opentest4j.AssertionFailedError: 
Expected :1000
Actual   :94
<Click to see difference>