Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/327.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 在单独线程中读取时关闭无限InputStream会导致死锁_Java_Multithreading - Fatal编程技术网

Java 在单独线程中读取时关闭无限InputStream会导致死锁

Java 在单独线程中读取时关闭无限InputStream会导致死锁,java,multithreading,Java,Multithreading,我有一个从输入流读取的线程,并且(为了简单起见)将其打印回控制台。请参见下面的代码片段 我希望能够在某个时刻终止这个线程,所以我应该能够通过关闭输入流来完成这项工作。这将导致抛出异常,中断BufferedReader::readLine方法,关闭线程 由于某种原因,close()调用挂起 发生这种情况的原因是什么?有没有一种方法可以关闭线程而不需要用户输入任何进一步的文本 导入java.io.BufferedReader; 导入java.io.IOException; 导入java.io.Inp

我有一个从输入流读取的线程,并且(为了简单起见)将其打印回控制台。请参见下面的代码片段

我希望能够在某个时刻终止这个线程,所以我应该能够通过关闭输入流来完成这项工作。这将导致抛出异常,中断
BufferedReader::readLine
方法,关闭线程

由于某种原因,
close()
调用挂起

发生这种情况的原因是什么?有没有一种方法可以关闭线程而不需要用户输入任何进一步的文本

导入java.io.BufferedReader;
导入java.io.IOException;
导入java.io.InputStream;
导入java.io.InputStreamReader;
公开课考试{
公共静态void main(字符串[]args)引发异常{
ReaderTest ReaderTest=新的ReaderTest(System.in);
新线程(readerTest).start();
睡眠(1000L);
System.out.println(“即将关闭…”);
System.in.close();//应该导致线程抛出异常并终止,但只是挂起
System.out.println(“全部关闭…”);
}
私有静态类ReaderTest实现可运行{
私有最终输入流InputStream;
公共读取器测试(InputStream InputStream){
this.inputStream=inputStream;
}
@凌驾
公开募捐{
试一试{
BufferedReader reader=新的BufferedReader(新的InputStreamReader(inputStream));
弦线;
而((line=reader.readLine())!=null){
系统输出打印项次(行);
}
}捕获(IOE异常){
e、 printStackTrace();
}
}
}
}
出于某种原因,close()调用只是挂起

您的线程正在等待
readLine()
释放锁:您正在使用

public ReaderTest(InputStream-InputStream){
this.inputStream=inputStream;//此inputStream(in from System.in)是一个监视器
}
while((line=reader.readLine())!=null){
系统输出打印项次(行);
}
readLine()
方法按以下步骤进行:

  • 锁定
    inputStream
    -这里是
    System.in
  • 进入无限循环(阻塞)等待输入
  • 当您在控制台上输入一行(并点击return或enter)时,它会读取这些行并返回输出,并立即释放锁
  • 然后它再次进入相同的无限(阻塞)循环(您正在while循环中调用
    readLine
如果您提供一些输入,主线程将执行
System.in.close()(因为读卡器线程瞬间释放锁)

因此,如果您在1秒后提供输入(
Thread.sleep(1000L);
),则
readLine()
将发现流已关闭,此时将抛出
java.io.IOException:stream closed

通过将读取块更新为以下内容,可以看到您输入的最后一行(在抛出
IOException
之前):

@覆盖
公开募捐{
String line=null;//使行在catch块内可访问
试一试{
BufferedReader reader=新的BufferedReader(新的InputStreamReader(inputStream));
而((line=reader.readLine())!=null){
系统输出打印项次(行);
}
}捕获(IOE异常){
System.out.println(“流关闭前我读取的最后一行:“+line”);
e、 printStackTrace();
}
}
出于某种原因,close()调用只是挂起

您的线程正在等待
readLine()
释放锁:您正在使用

public ReaderTest(InputStream-InputStream){
this.inputStream=inputStream;//此inputStream(in from System.in)是一个监视器
}
while((line=reader.readLine())!=null){
系统输出打印项次(行);
}
readLine()
方法按以下步骤进行:

  • 锁定
    inputStream
    -这里是
    System.in
  • 进入无限循环(阻塞)等待输入
  • 当您在控制台上输入一行(并点击return或enter)时,它会读取这些行并返回输出,并立即释放锁
  • 然后它再次进入相同的无限(阻塞)循环(您正在while循环中调用
    readLine
如果您提供一些输入,主线程将执行
System.in.close()(因为读卡器线程瞬间释放锁)

因此,如果您在1秒后提供输入(
Thread.sleep(1000L);
),则
readLine()
将发现流已关闭,此时将抛出
java.io.IOException:stream closed

通过将读取块更新为以下内容,可以看到您输入的最后一行(在抛出
IOException
之前):

@覆盖
公开募捐{
String line=null;//使行在catch块内可访问
试一试{
BufferedReader reader=新的BufferedReader(新的InputStreamReader(inputStream));
而((line=reader.readLine())!=null){
系统输出打印项次(行);
}
}捕获(IOE异常){
System.out.println(“流关闭前我读取的最后一行:“+line”);
e、 printStackTrace();
}
}

它可能与
系统有关。在
中,更改主输入:

publicstaticvoidmain(字符串[]args)引发异常{
ServerSocket=新的ServerSocket(8883);
InputStream=socket.accept().getInputStream();
ReaderTest ReaderTest=新的ReaderTest(is);
新线程(readerTest).start();
睡眠(1000L);
System.out.println(“即将关闭…”);
is.close();//原因