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();//原因