IO异常 - 读取结束死机 - 在此示例中导致它的原因以及如何修复它 - Java中的多线程应用程序(IO Exception - read end dead - what causes it in this example and how to fix it - multithread application in Java)
这是我在这里发布的问题的扩展 ,虽然这似乎解决了我的问题的一部分,现在我看到
IO-Exception read end dead exception
。 我使用的是multithreaded
应用程序,其中thread-1 produces
随机数,而其他thread-2 consumes
它来计算平均值。 一旦平均值达到阈值,我发信号通知thread-1
停止产生数字。 这是代码的基本设计。我收到
IO-Exception read end dead exception
。 我想知道为什么会这样,以及如何解决它。 谢谢。代码如下:
import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; import java.io.PipedInputStream; import java.io.PipedOutputStream; import java.util.Random; import java.util.concurrent.atomic.AtomicBoolean; // class NumGen extends Thread { PipedOutputStream pos; DataOutputStream dos; AtomicBoolean isDone; public NumGen(PipedOutputStream pos,AtomicBoolean isDone){ this.pos=pos; dos=new DataOutputStream(pos); this.isDone=isDone; } public void run(){ while (!isDone.get()){ Random rand = new Random(); try { dos.writeDouble(rand.nextDouble()+100.0); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } class RunningAvg extends Thread { PipedInputStream pis; DataInputStream dis; Double avg; int count; Double runningTotal; AtomicBoolean isDone; public RunningAvg(PipedInputStream pis,AtomicBoolean isDone){ this.pis=pis; dis=new DataInputStream(pis); runningTotal=0.0; avg=0.0; this.isDone=isDone; } public void run(){ try { while (dis.available()>0){ count+=1; runningTotal+=dis.readDouble(); avg=runningTotal/count; System.out.printf("The average in count no : %s is %s%n",count,avg); if (avg>1E5) isDone.set(true); } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } public class InterThreadComm { public static void main(String[] args){ try { PipedOutputStream pos= new PipedOutputStream(); PipedInputStream pis = new PipedInputStream(pos); AtomicBoolean isDone = new AtomicBoolean(false); NumGen ng = new NumGen(pos,isDone); RunningAvg ra = new RunningAvg(pis,isDone); ng.start(); ra.start(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
编辑:根据以下答案:我尝试使用try-with-resources关闭Streams。 但我得到
java.io.IOException: Pipe closed
public class InterThreadComm { public static void main(String[] args){ try(PipedOutputStream pos= new PipedOutputStream();PipedInputStream pis =new PipedInputStream(pos)){ AtomicBoolean isDone = new AtomicBoolean(false); NumGen ng = new NumGen(pos,isDone); RunningAvg ra = new RunningAvg(pis,isDone); ng.start(); ra.start(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
This is an extension of my question posted here, while that seems to have fixed one part of my problem, now I see
IO-Exception read end dead exception
. I am using amultithreaded
application wherethread-1 produces
random numbers and otherthread-2 consumes
it to calculate the average. once the average reaches a threshold, I signalthread-1
to stop producing the numbers. This is the basic design of the code.I am getting
IO-Exception read end dead exception
. I want to know why it comes and how to fix it. Thanks.The code below :
import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; import java.io.PipedInputStream; import java.io.PipedOutputStream; import java.util.Random; import java.util.concurrent.atomic.AtomicBoolean; // class NumGen extends Thread { PipedOutputStream pos; DataOutputStream dos; AtomicBoolean isDone; public NumGen(PipedOutputStream pos,AtomicBoolean isDone){ this.pos=pos; dos=new DataOutputStream(pos); this.isDone=isDone; } public void run(){ while (!isDone.get()){ Random rand = new Random(); try { dos.writeDouble(rand.nextDouble()+100.0); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } class RunningAvg extends Thread { PipedInputStream pis; DataInputStream dis; Double avg; int count; Double runningTotal; AtomicBoolean isDone; public RunningAvg(PipedInputStream pis,AtomicBoolean isDone){ this.pis=pis; dis=new DataInputStream(pis); runningTotal=0.0; avg=0.0; this.isDone=isDone; } public void run(){ try { while (dis.available()>0){ count+=1; runningTotal+=dis.readDouble(); avg=runningTotal/count; System.out.printf("The average in count no : %s is %s%n",count,avg); if (avg>1E5) isDone.set(true); } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } public class InterThreadComm { public static void main(String[] args){ try { PipedOutputStream pos= new PipedOutputStream(); PipedInputStream pis = new PipedInputStream(pos); AtomicBoolean isDone = new AtomicBoolean(false); NumGen ng = new NumGen(pos,isDone); RunningAvg ra = new RunningAvg(pis,isDone); ng.start(); ra.start(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
EDIT: As per the answer below: I tried to close the Streams using try-with-resources. but I get
java.io.IOException: Pipe closed
public class InterThreadComm { public static void main(String[] args){ try(PipedOutputStream pos= new PipedOutputStream();PipedInputStream pis =new PipedInputStream(pos)){ AtomicBoolean isDone = new AtomicBoolean(false); NumGen ng = new NumGen(pos,isDone); RunningAvg ra = new RunningAvg(pis,isDone); ng.start(); ra.start(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
原文:https://stackoverflow.com/questions/22181107
最满意答案
这里是ParseKit的开发者。
使用ParseKit(或任何解析工具包)执行此操作的最简单和最优雅的方法可能是设计您的公式语言在每个语句后都有一个终结符char。 这与概念相同
;
在大多数类C编程语言中终止语句。这是一个使用的玩具公式语言示例
.
作为声明终结者:@start = lang; lang = statment+; statment = Word+ terminator; terminator = '.';
请注意我是如何设计语言的,以便您的“贪婪”要求是该语言的固有特征。 想想看 - 如果输入字符串以任何垃圾内容结尾,而垃圾内容不是以a结尾的有效语句
.
,我的lang
生产将找不到匹配,解析将失败。使用这种类型的设计,您在使用的解析工具箱中不需要任何“贪婪”功能。 相反,您的语言设计自然会满足您的要求。
Developer of ParseKit here.
Probably the simplest and most elegant way to do this with ParseKit (or any parsing toolkit) is to design your formula language have a terminator char after every statement. This would be the same concept as
;
terminating statements in most C-like programming languages.Here's an example toy formula language which uses
.
as the statement terminator:@start = lang; lang = statment+; statment = Word+ terminator; terminator = '.';
Notice how I have designed the language so that your "greedy" requirement is an inherent feature of the language. Think about it – if the input string ends with any junk content which is not a valid statement ending in a
.
, mylang
production will not find a match and the parse will fail.With this type of design, you won't need any "greedy" features in the parsking toolkit you use. Rather, your requirement will be naturally met by your language design.
相关问答
更多-
不贪婪? 工作完好无损。 只是你需要在正则表达式引擎中选择点匹配所有选项(正则表达式,你使用的引擎,还有这个选项),你正在测试。 这是因为正则表达式引擎通常在使用时不符合换行符. 。 你需要明确地告诉他们你也想要匹配换行符. 例如, 工作正常! 检查结果在这里 。 另外,请阅读各种正则表达式的行为 。 The non-greedy ? works perfectly fine. It's just that you need to select dot matches all opt ...
-
基本和扩展的Posix / GNU正则表达式都不识别非贪心量词; 你需要一个后来的正则表达式。 幸运的是,这个上下文的Perl正则表达式很容易得到: perl -pe 's|(http://.*?/).*|\1|' Neither basic nor extended Posix/GNU regex recognizes the non-greedy quantifier; you need a later regex. Fortunately, Perl regex for this context i ...
-
像\w , \d和\s这样的字符类缩写与完全相同的内部字符类,但是像元字符一样. 通常会在角色类中失去特殊含义。 这就是为什么/ // !-- [.] //没有按预期工作的原因: [.]匹配文字. 。 但是/ /! - 。 //也不起作用,因为. 与换行符不匹配。 在大多数正则表达式中,您可以使用单行模式让点匹配包括换行符在内的所有字符,如: //s (?s)或此:( (?s) 。 但Java ...
-
如何与python(复杂的非贪婪模式)进行最短匹配(how to get the shortest matching with python (complex non-greedy pattern))[2023-05-01]
你可以使用这个基于前瞻性的正则表达式: >>> print re.findall(r"'''(?:(?!''').)*''' is a \[\[.*?\]\]", line) ["'''starter culture''' is a [[microbiological culture]]"] (?:(?!''').)*将匹配0或更多在下一个位置没有'''字符,从而确保匹配两个'''之间的最短匹配 。 RegEx演示 You can use this lookahead based regex: >>> p ... -
与grep非贪婪匹配(Non-greedy matching with grep)[2022-06-30]
双量词只是一个语法错误,可能会导致错误消息或未定义的行为。 如果您收到错误消息,这可能会更好。 大量的Perl扩展到正则表达式POSIX; 在写这些工具的时候,有人不太可能会试图用这种古怪的语法来做任何事情。 贪婪的匹配仅在20世纪90年代中期在Perl 5中引入。 The double quantifier is simply a syntax error and could result in either an error message or undefined behavior. It would ... -
sed正则表达不贪心?(sed regex not being greedy?)[2023-10-16]
问题是.*也很贪婪,这意味着它也会获得所有数字。 因为你强制它在[0-9][0-9]*部分中至少获得一个数字,所以.*之前的.*将足够贪婪,只留下一个数字后面的表达式。 解决方案可能是: echo ${tempvar} | sed -r "s/^.*\s([0-9][0-9]*):\sMesh\sTally\sNumber\s${meshnum1}.*$/\1/" 现在, .*和[0-9][0-9]*之间的\s显式强制在你想要匹配的数字之前有一个空格。 希望这有助于=) The problem is th ... -
ParseKit贪心匹配模式(ParseKit greedy matching mode)[2023-11-13]
这里是ParseKit的开发者。 使用ParseKit(或任何解析工具包)执行此操作的最简单和最优雅的方法可能是设计您的公式语言在每个语句后都有一个终结符char。 这与概念相同; 在大多数类C编程语言中终止语句。 这是一个使用的玩具公式语言示例. 作为声明终结者: @start = lang; lang = statment+; statment = Word+ terminator; terminator = '.'; 请注意我是如何设计语言的,以便您的“贪婪”要求是该语言的固有特征。 想想看 - 如 ... -
我倾向于使用更像: [^/]+/([^/]+)/([^/]+)/topic/(.+) 这个想法不是匹配任何字符,而是匹配下一个斜杠。 括号[]定义一个字符类,代字号, ~ ,表示'不',所以[^/]匹配除斜杠之外的所有内容。 I tend to use something more like: [^/]+/([^/]+)/([^/]+)/topic/(.+) The idea is instead of matching any character, you match up to the next s ...
-
我在Regex lazy vs greedy confusion的帮助下找到了一个解决方案。 在像Javascript(我相信的NFA引擎 )那样的正则表达式引擎中,非贪婪只能从左到右匹配最短的匹配 - 从适合最近的右手匹配的第一个左手匹配。 如果一场右手比赛有很多左手比赛,那么它将始终从它到达的第一场比赛开始(这实际上会给出最长的比赛)。 基本上,它一次通过字符串一个字符询问“这个字符是否匹配?如果是,匹配最短并完成。如果不是,请转到下一个字符,重复”。 我期望它是“在这个字符串中的任何地方都有匹配吗?如 ...
-
反例: a1 a2 a3 a4 a5 p1 x x p2 x x x x p3 x x x x p4 x p5 x x x 首先选择a5。 随机选择可能是p5的飞行员。 如果是,p4没有飞机。 counter-example: a1 a2 a3 a4 a5 p1 x x p2 x x x x p3 x x x ...