MST

星途 面试题库

面试题:Java中阻塞IO如何影响线程资源

请详细阐述在Java中,阻塞IO操作是怎样影响线程资源的分配与使用的,举例说明常见的阻塞IO场景及对线程状态的改变。
24.1万 热度难度
编程语言Java

知识考点

AI 面试

面试题答案

一键面试

阻塞IO对线程资源分配与使用的影响

  1. 线程资源占用:当线程执行阻塞IO操作时,该线程会被挂起,等待IO操作完成。在此期间,线程无法执行其他任务,但依然占用着系统分配给它的资源,如栈空间等。这意味着在阻塞期间,线程不能被调度去执行其他代码逻辑,造成了线程资源的浪费。
  2. 线程调度:操作系统的线程调度器会将CPU时间分配给其他可运行的线程。阻塞IO操作使得当前线程从运行状态变为阻塞状态,让出CPU,直到IO操作完成,线程才会重新变为可运行状态,等待调度器再次分配CPU时间。

常见阻塞IO场景及对线程状态的改变

  1. 文件读取
    • 场景:使用FileInputStream读取文件内容时,如下代码:
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;

public class FileReadExample {
    public static void main(String[] args) {
        try (InputStream inputStream = new FileInputStream("example.txt")) {
            byte[] buffer = new byte[1024];
            int bytesRead = inputStream.read(buffer);
            while (bytesRead != -1) {
                // 处理读取到的字节
                bytesRead = inputStream.read(buffer);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
  • 线程状态改变:当执行inputStream.read(buffer)时,如果文件内容还未准备好(例如文件正在从磁盘中读取到内存),线程会从运行状态变为阻塞状态。一旦数据可读,线程会从阻塞状态变为可运行状态,执行后续的读取和处理逻辑。
  1. 网络Socket读取
    • 场景:使用Socket进行网络通信,接收数据时,如下代码:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;

public class SocketReadExample {
    public static void main(String[] args) {
        try (ServerSocket serverSocket = new ServerSocket(8080)) {
            try (Socket clientSocket = serverSocket.accept()) {
                BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
                String inputLine;
                while ((inputLine = in.readLine()) != null) {
                    System.out.println("Received: " + inputLine);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
  • 线程状态改变:当执行in.readLine()时,如果没有数据到达网络缓冲区,线程会从运行状态变为阻塞状态。当数据到达,线程会从阻塞状态变为可运行状态,读取并处理接收到的数据。