文字列を渡すことができるInputStreamを実装しようとしました。
技術的には、私がする必要があったのはInputStream#read()メソッドをブロックすることだけだったので、うまくいくはずです。LinkedBlockingQueueがハングするInputStreamのカスタム実装
public class StringInputStream extends InputStream {
private LinkedBlockingQueue<Integer> buffer = new LinkedBlockingQueue<>();
public void supplyData(String s) {
for (char ch : s.toCharArray()) {
buffer.add((int) ch);
}
}
@Override
public int read() throws IOException {
try {
return buffer.take();
} catch (InterruptedException e) {
e.printStackTrace();
}
return -1;
}
}
そして、ここではそれをテストするために私のコードです:
public class StreamsMain {
public static void main(String[] args) throws InterruptedException {
InputStream is = new ByteArrayInputStream("eu ma duc la scoala\n sa ma distrez\nsi imi place la MAXIM!".getBytes(StandardCharsets.UTF_8));
Scanner scanner1 = new Scanner(is);
AtomicReference<StringInputStream> inputStream = new AtomicReference<>(new StringInputStream());
Thread th = new Thread(() -> {
Scanner scanner = new Scanner(inputStream.get());
while (scanner.hasNextLine()) {
System.out.println("2. " + scanner.nextLine());
}
});
th.start();
while (scanner1.hasNextLine()) {
String line = scanner1.nextLine();
inputStream.get().supplyData(line + "\n");
System.out.println("1. " + line);
}
System.out.println("\n\nwaiting 3 seconds to exit from MAIN thread");
TimeUnit.SECONDS.sleep(3);
//th.interrupt();
System.out.println("exited MAIN thread");
}
}
私の例では、私はから読んでいるか、私はそう...ここ はStringInputStreamの私のカスタム実装であると思いました最初のinputstream、私は私のカスタム実装にラインを供給し、私は別のスレッドで私のカスタム実装から読んでいます。
私はth.interrupt()行を分解しない限り、出力が表示されません。他のスレッドのStringInputStream)。
問題を見つけてもらえますか?
敬具、
FYI: 'InputStream'は_bytes_を読み込むためのものです。 'Reader'は_characters_またはStringsを読み込むためのものです。あなたは本当に_二つを混ぜ合わせてはいけません。 –
'Scanner'はバッファされたI/Oを使うと思います。プッシュする内容はすべてこのバッファサイズより小さくなります。そのため、何も入力していないときに、より多くの着信データを待っています。中断したときにファイルの終わりを-1と返すので、待機を終了します。正しい解決策は、消費スレッドが読むことができるストリームに何らかのファイル終わりマーカーをプッシュすることです。 – Holger