- 资源管理注意点
- 延迟执行导致资源关闭时机问题:Stream是延迟执行的,这意味着操作不会立即执行,只有在终端操作时才会执行。如果在Stream操作中涉及到需要及时关闭的资源(如文件句柄、数据库连接),若不妥善处理,可能在终端操作前资源无法关闭,导致资源泄露。
- 并行流中的资源管理:在并行流中,资源管理会更加复杂,因为操作可能在多个线程中并行执行,需要确保资源在多线程环境下安全使用和关闭。
- 避免资源泄露示例 - 使用
try - with - resources
结合Stream
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.stream.Stream;
public class StreamResourceManagement {
public static void main(String[] args) {
String filePath = "example.txt";
try (BufferedReader br = new BufferedReader(new FileReader(filePath))) {
Stream<String> lines = br.lines();
long lineCount = lines.count();
System.out.println("Line count: " + lineCount);
} catch (IOException e) {
e.printStackTrace();
}
}
}
- 在上述代码中,使用
try - with - resources
语句来管理BufferedReader
。在try
块中创建BufferedReader
,并通过br.lines()
获取Stream。即使Stream操作延迟执行,当try
块结束(无论是正常结束还是抛出异常)时,BufferedReader
会自动关闭,避免了文件句柄的泄露。
- 数据库连接示例
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.stream.Stream;
public class DatabaseStreamResourceManagement {
public static void main(String[] args) {
String url = "jdbc:mysql://localhost:3306/mydb";
String user = "root";
String password = "password";
try (Connection conn = DriverManager.getConnection(url, user, password);
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("SELECT * FROM users")) {
Stream<String> userNames = Stream.generate(() -> {
try {
if (rs.next()) {
return rs.getString("username");
} else {
return null;
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}).takeWhile(s -> s != null);
userNames.forEach(System.out::println);
} catch (Exception e) {
e.printStackTrace();
}
}
}
- 在这个示例中,通过
try - with - resources
管理Connection
、Statement
和ResultSet
。try
块结束时,这些数据库相关资源会自动关闭,避免数据库连接泄露,即使Stream操作是延迟执行的。同时,在通过Stream.generate
创建Stream时,正确处理了ResultSet
的迭代,确保在数据读取完后Stream能正确结束。