Java中使用use模式管理AutoCloseable文件的高效按需处理方案
解决方案
1. 缓存宏解析结果,消除重复解析
重复解析宏代码是核心性能损耗点,将宏解析逻辑抽离为独立模块,用线程安全的缓存存储解析后的结果,确保同一段宏代码仅被解析一次:
public class MacroParser { // 用ConcurrentHashMap保证多线程下的缓存安全 private static final Map<String, ParsedMacro> PARSED_MACRO_CACHE = new ConcurrentHashMap<>(); public static ParsedMacro parse(String macroCode) { // 仅当缓存中无对应结果时才执行解析逻辑 return PARSED_MACRO_CACHE.computeIfAbsent(macroCode, rawCode -> { ParsedMacro parsed = new ParsedMacro(); // 这里放入你的宏解析逻辑,比如语法分析、变量替换等 // parsed.setXXX(...); return parsed; }); } }
2. 基于工厂模式+use函数,实现按需文件生成
摒弃嵌套use的冗余写法,用工厂类根据用户选择动态创建对应FileInterface实例,再通过统一的use函数处理资源自动关闭,自然跳过不需要的文件类型:
实现Venkat风格的use工具函数
public class ResourceManager { /** * 封装AutoCloseable资源的使用逻辑,自动处理关闭与异常 * @param resource 实现AutoCloseable的资源实例 * @param action 资源的业务处理逻辑 * @return 业务逻辑的返回结果 * @param <R> 资源类型 * @param <T> 返回值类型 */ public static <R extends AutoCloseable, T> T use(R resource, Function<R, T> action) { try (R res = resource) { return action.apply(res); } catch (Exception e) { // 可根据业务需求调整异常处理,比如转为自定义业务异常 throw new RuntimeException("文件写入失败", e); } } }
实现FileInterface工厂类
public class FileWriterFactory { public static FileInterface createWriter(String fileType) { return switch (fileType.toUpperCase()) { case "TABLE" -> new FileTable(); case "WEB" -> new FileWeb(); // 扩展其他文件类型的实现 default -> throw new IllegalArgumentException("不支持的文件类型: " + fileType); }; } }
业务流程调用示例
public void generateSelectedFile(String userSelectedType, String macroCode) { // 仅解析一次宏代码 ParsedMacro parsedMacro = MacroParser.parse(macroCode); // 根据用户选择创建对应写入器,自动跳过未选中的类型 FileInterface fileWriter = FileWriterFactory.createWriter(userSelectedType); // 用use函数处理资源,无需手动管理关闭 ResourceManager.use(fileWriter, writer -> { writer.write(parsedMacro); return null; // 若需返回结果,可替换为实际返回值 }); }
3. 安全并行处理方案(若需批量生成)
如果存在批量生成多种文件类型的场景,避免无限制并行导致内存溢出,使用固定大小线程池控制并发数,结合缓存的宏解析结果:
// 根据服务器CPU核心数或内存配置调整线程池大小 private static final ExecutorService FILE_GENERATION_POOL = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors()); public void generateBatchFiles(List<String> selectedFileTypes, String macroCode) { ParsedMacro parsedMacro = MacroParser.parse(macroCode); // 提交并行任务,控制并发数 List<CompletableFuture<Void>> tasks = selectedFileTypes.stream() .map(type -> CompletableFuture.runAsync(() -> { FileInterface writer = FileWriterFactory.createWriter(type); ResourceManager.use(writer, w -> { w.write(parsedMacro); return null; }); }, FILE_GENERATION_POOL)) .toList(); // 等待所有任务完成 CompletableFuture.allOf(tasks.toArray(new CompletableFuture[0])).join(); }
额外优化建议
- 给
FileInterface实现类添加带参数的构造方法,提前传入必要配置(如文件路径、编码),避免重复初始化资源 - 针对不同文件类型的写入异常,可在
use函数或工厂类中添加差异化处理逻辑 - 若宏代码存在动态更新需求,可为缓存添加过期时间,或提供手动清理缓存的方法
内容的提问来源于stack exchange,提问作者Tugalsan Karabacak
相关产品推荐
相关产品推荐

