|
|
@@ -1,307 +0,0 @@
|
|
|
-package top.imwork.exercise;
|
|
|
-
|
|
|
-import java.io.IOException;
|
|
|
-import java.nio.file.Files;
|
|
|
-import java.nio.file.Path;
|
|
|
-import java.nio.file.Paths;
|
|
|
-import java.util.List;
|
|
|
-import java.util.Scanner;
|
|
|
-
|
|
|
-public class Main {
|
|
|
- public static void main(String[] args) {
|
|
|
- Scanner scanner = new Scanner(System.in);
|
|
|
-
|
|
|
- System.out.println("=== TXT文件章节分割器 ===");
|
|
|
- System.out.println("Java版本: " + System.getProperty("java.version"));
|
|
|
- System.out.println("虚拟线程支持: " + (checkVirtualThreadSupport() ? "是" : "否"));
|
|
|
- System.out.println("结构化并发支持: " + (checkStructuredConcurrencySupport() ? "是" : "否"));
|
|
|
-
|
|
|
- System.out.println("\n请选择运行模式:");
|
|
|
- System.out.println("1. 使用虚拟线程");
|
|
|
- System.out.println("2. 使用传统线程池");
|
|
|
- System.out.println("3. 使用并行流");
|
|
|
- System.out.println("4. 使用结构化并发(预览功能)");
|
|
|
- System.out.println("5. 生成示例文件并测试所有模式");
|
|
|
- System.out.println("6. 性能对比测试");
|
|
|
-
|
|
|
- System.out.print("请选择 (1-6): ");
|
|
|
- int choice = scanner.nextInt();
|
|
|
- scanner.nextLine(); // 消耗换行符
|
|
|
-
|
|
|
- try {
|
|
|
- switch (choice) {
|
|
|
- case 1:
|
|
|
- runWithVirtualThreads(scanner);
|
|
|
- break;
|
|
|
- case 2:
|
|
|
- runWithThreadPool(scanner);
|
|
|
- break;
|
|
|
- case 3:
|
|
|
- runWithParallelStream(scanner);
|
|
|
- break;
|
|
|
- case 4:
|
|
|
- runWithStructuredConcurrency(scanner);
|
|
|
- break;
|
|
|
- case 5:
|
|
|
- generateSampleFileAndTest();
|
|
|
- break;
|
|
|
- case 6:
|
|
|
- runPerformanceComparison();
|
|
|
- break;
|
|
|
- default:
|
|
|
- System.out.println("无效选择,使用虚拟线程模式");
|
|
|
- runWithVirtualThreads(scanner);
|
|
|
- }
|
|
|
- } catch (Exception e) {
|
|
|
- System.err.println("程序执行出错: " + e.getMessage());
|
|
|
- e.printStackTrace();
|
|
|
- } finally {
|
|
|
- scanner.close();
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- private static boolean checkVirtualThreadSupport() {
|
|
|
- try {
|
|
|
- Executors.class.getMethod("newVirtualThreadPerTaskExecutor");
|
|
|
- return true;
|
|
|
- } catch (NoSuchMethodException e) {
|
|
|
- return false;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- private static boolean checkStructuredConcurrencySupport() {
|
|
|
- try {
|
|
|
- Class.forName("java.util.concurrent.StructuredTaskScope");
|
|
|
- return true;
|
|
|
- } catch (ClassNotFoundException e) {
|
|
|
- return false;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- private static void runWithVirtualThreads(Scanner scanner) throws Exception {
|
|
|
- if (!checkVirtualThreadSupport()) {
|
|
|
- System.out.println("当前Java版本不支持虚拟线程!");
|
|
|
- System.out.println("请使用Java 21或更高版本,并添加--enable-preview参数");
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- String[] fileAndOutput = getFileAndOutputPath(scanner);
|
|
|
- ChapterSplitter splitter = new ChapterSplitter(fileAndOutput[0], true);
|
|
|
- System.out.println("开始使用虚拟线程处理章节...");
|
|
|
-
|
|
|
- List<Chapter> chapters = splitter.splitWithVirtualThreads();
|
|
|
-
|
|
|
- splitter.printStatistics(chapters);
|
|
|
- splitter.saveChaptersToFiles(chapters, fileAndOutput[1]);
|
|
|
-
|
|
|
- System.out.println("处理完成!");
|
|
|
- }
|
|
|
-
|
|
|
- private static void runWithThreadPool(Scanner scanner) throws Exception {
|
|
|
- System.out.print("请输入线程池大小(默认为CPU核心数): ");
|
|
|
- String threadCountStr = scanner.nextLine();
|
|
|
- int threadCount = threadCountStr.isEmpty()
|
|
|
- ? Runtime.getRuntime().availableProcessors()
|
|
|
- : Integer.parseInt(threadCountStr);
|
|
|
-
|
|
|
- String[] fileAndOutput = getFileAndOutputPath(scanner);
|
|
|
- ChapterSplitter splitter = new ChapterSplitter(fileAndOutput[0], false);
|
|
|
- System.out.printf("开始使用线程池(%d线程)处理章节...%n", threadCount);
|
|
|
-
|
|
|
- List<Chapter> chapters = splitter.splitWithThreadPool(threadCount);
|
|
|
-
|
|
|
- splitter.printStatistics(chapters);
|
|
|
- splitter.saveChaptersToFiles(chapters, fileAndOutput[1]);
|
|
|
-
|
|
|
- System.out.println("处理完成!");
|
|
|
- }
|
|
|
-
|
|
|
- private static void runWithParallelStream(Scanner scanner) throws Exception {
|
|
|
- String[] fileAndOutput = getFileAndOutputPath(scanner);
|
|
|
- ChapterSplitter splitter = new ChapterSplitter(fileAndOutput[0], false);
|
|
|
- System.out.println("开始使用并行流处理章节...");
|
|
|
-
|
|
|
- List<Chapter> chapters = splitter.splitWithParallelStream();
|
|
|
-
|
|
|
- splitter.printStatistics(chapters);
|
|
|
- splitter.saveChaptersToFiles(chapters, fileAndOutput[1]);
|
|
|
-
|
|
|
- System.out.println("处理完成!");
|
|
|
- }
|
|
|
-
|
|
|
- private static void runWithStructuredConcurrency(Scanner scanner) throws Exception {
|
|
|
- if (!checkStructuredConcurrencySupport()) {
|
|
|
- System.out.println("当前Java版本不支持结构化并发!");
|
|
|
- System.out.println("请使用Java 21或更高版本,并添加--enable-preview参数");
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- String[] fileAndOutput = getFileAndOutputPath(scanner);
|
|
|
- ChapterSplitter splitter = new ChapterSplitter(fileAndOutput[0], true);
|
|
|
- System.out.println("开始使用结构化并发处理章节...");
|
|
|
-
|
|
|
- List<Chapter> chapters = splitter.splitWithStructuredConcurrency();
|
|
|
-
|
|
|
- splitter.printStatistics(chapters);
|
|
|
- splitter.saveChaptersToFiles(chapters, fileAndOutput[1]);
|
|
|
-
|
|
|
- System.out.println("处理完成!");
|
|
|
- }
|
|
|
-
|
|
|
- private static String[] getFileAndOutputPath(Scanner scanner) throws IOException {
|
|
|
- System.out.print("请输入TXT文件路径: ");
|
|
|
- String filePath = scanner.nextLine();
|
|
|
-
|
|
|
- if (!Files.exists(Paths.get(filePath))) {
|
|
|
- System.out.println("文件不存在,使用示例文件");
|
|
|
- filePath = "sample.txt";
|
|
|
- if (!Files.exists(Paths.get(filePath))) {
|
|
|
- generateSampleFile();
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- System.out.print("请输入输出目录(默认为output): ");
|
|
|
- String outputDir = scanner.nextLine();
|
|
|
- if (outputDir.isEmpty()) {
|
|
|
- outputDir = "output";
|
|
|
- }
|
|
|
-
|
|
|
- return new String[]{filePath, outputDir};
|
|
|
- }
|
|
|
-
|
|
|
- private static void generateSampleFileAndTest() throws Exception {
|
|
|
- generateSampleFile();
|
|
|
-
|
|
|
- System.out.println("已生成示例文件,开始测试各种模式...\n");
|
|
|
-
|
|
|
- String[] testCases = {
|
|
|
- "虚拟线程", "传统线程池", "并行流", "结构化并发"
|
|
|
- };
|
|
|
-
|
|
|
- for (String testCase : testCases) {
|
|
|
- System.out.println("\n=== 测试" + testCase + " ===");
|
|
|
- try {
|
|
|
- testProcessingMode(testCase);
|
|
|
- } catch (Exception e) {
|
|
|
- System.out.println(testCase + " 测试失败: " + e.getMessage());
|
|
|
- }
|
|
|
- System.out.println("等待3秒...\n");
|
|
|
- Thread.sleep(3000);
|
|
|
- }
|
|
|
-
|
|
|
- System.out.println("所有测试完成!");
|
|
|
- }
|
|
|
-
|
|
|
- private static void testProcessingMode(String mode) throws Exception {
|
|
|
- ChapterSplitter splitter = new ChapterSplitter("sample.txt", true);
|
|
|
- List<Chapter> chapters;
|
|
|
-
|
|
|
- switch (mode) {
|
|
|
- case "虚拟线程":
|
|
|
- if (!checkVirtualThreadSupport()) {
|
|
|
- System.out.println("跳过 - 不支持虚拟线程");
|
|
|
- return;
|
|
|
- }
|
|
|
- chapters = splitter.splitWithVirtualThreads();
|
|
|
- break;
|
|
|
- case "传统线程池":
|
|
|
- chapters = splitter.splitWithThreadPool(4);
|
|
|
- break;
|
|
|
- case "并行流":
|
|
|
- chapters = splitter.splitWithParallelStream();
|
|
|
- break;
|
|
|
- case "结构化并发":
|
|
|
- if (!checkStructuredConcurrencySupport()) {
|
|
|
- System.out.println("跳过 - 不支持结构化并发");
|
|
|
- return;
|
|
|
- }
|
|
|
- chapters = splitter.splitWithStructuredConcurrency();
|
|
|
- break;
|
|
|
- default:
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- splitter.printStatistics(chapters);
|
|
|
- splitter.saveChaptersToFiles(chapters, "output_" + mode);
|
|
|
- }
|
|
|
-
|
|
|
- private static void runPerformanceComparison() throws Exception {
|
|
|
- generateSampleFile();
|
|
|
-
|
|
|
- System.out.println("开始性能对比测试...\n");
|
|
|
-
|
|
|
- // 测试不同模式
|
|
|
- String[][] testConfigs = {
|
|
|
- {"虚拟线程", "true"},
|
|
|
- {"传统线程池-4线程", "false"},
|
|
|
- {"传统线程池-8线程", "false"},
|
|
|
- {"并行流", "false"}
|
|
|
- };
|
|
|
-
|
|
|
- for (String[] config : testConfigs) {
|
|
|
- String name = config[0];
|
|
|
- boolean useVirtual = Boolean.parseBoolean(config[1]);
|
|
|
-
|
|
|
- System.out.println("测试模式: " + name);
|
|
|
-
|
|
|
- long startTime = System.currentTimeMillis();
|
|
|
- ChapterSplitter splitter = new ChapterSplitter("sample.txt", useVirtual);
|
|
|
-
|
|
|
- List<Chapter> chapters;
|
|
|
- if (name.contains("虚拟线程")) {
|
|
|
- chapters = splitter.splitWithVirtualThreads();
|
|
|
- } else if (name.contains("传统线程池")) {
|
|
|
- int threads = Integer.parseInt(name.split("-")[1].replace("线程", ""));
|
|
|
- chapters = splitter.splitWithThreadPool(threads);
|
|
|
- } else {
|
|
|
- chapters = splitter.splitWithParallelStream();
|
|
|
- }
|
|
|
-
|
|
|
- long endTime = System.currentTimeMillis();
|
|
|
- long duration = endTime - startTime;
|
|
|
-
|
|
|
- System.out.printf("处理时间: %d ms, 章节数: %d, 总字数: %,d%n%n",
|
|
|
- duration, chapters.size(),
|
|
|
- chapters.stream().mapToInt(Chapter::getWordCount).sum());
|
|
|
-
|
|
|
- Thread.sleep(1000); // 等待1秒
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- private static void generateSampleFile() throws IOException {
|
|
|
- String sampleContent = buildSampleContent();
|
|
|
- Files.writeString(Paths.get("sample.txt"), sampleContent);
|
|
|
- System.out.println("已生成示例文件: sample.txt");
|
|
|
- System.out.printf("文件大小: %,d 字节%n", Files.size(Paths.get("sample.txt")));
|
|
|
- }
|
|
|
-
|
|
|
- private static String buildSampleContent() {
|
|
|
- StringBuilder sb = new StringBuilder();
|
|
|
-
|
|
|
- sb.append("第零章 前言\n\n");
|
|
|
- sb.append("这是一个示例文本文件,用于测试章节分割功能。\n");
|
|
|
- sb.append("本文件包含多个章节,每个章节都有不同的内容。\n\n");
|
|
|
-
|
|
|
- // 生成更多章节用于测试
|
|
|
- for (int i = 1; i <= 100; i++) {
|
|
|
- sb.append(String.format("第%d章 章节标题%d\n\n", i, i));
|
|
|
- sb.append("这是第").append(i).append("章的内容。\n");
|
|
|
- sb.append("本章节包含一些示例文本,用于演示多线程处理能力。\n");
|
|
|
-
|
|
|
- // 添加一些变长内容
|
|
|
- int paragraphCount = i % 20 + 1;
|
|
|
- for (int j = 0; j < paragraphCount; j++) {
|
|
|
- sb.append("虚拟线程是Java 21引入的重要特性,它使得高并发编程更加简单高效。");
|
|
|
- sb.append("通过虚拟线程,我们可以创建数百万个线程而不用担心系统资源耗尽。");
|
|
|
- sb.append("这种轻量级线程非常适合I/O密集型任务,如文件处理、网络请求等。");
|
|
|
- }
|
|
|
- sb.append("\n\n");
|
|
|
- }
|
|
|
-
|
|
|
- sb.append("第一百零一章 终章\n\n");
|
|
|
- sb.append("这是最后一个章节,标志着本书的结束。\n");
|
|
|
- sb.append("感谢阅读!\n");
|
|
|
-
|
|
|
- return sb.toString();
|
|
|
- }
|
|
|
-}
|