帮忙出一个 多线程在实际项目中的示例

欣喜 Java经验 发布时间:2025-03-21 09:39:29 阅读数:155 1
下文笔者讲述使用多线程处理日志文件压缩和移动的示例分享

日志文件压缩和移动

项目结构
 
log-processing/
├── src/
│   └── main/
│       └── java/
│           └── com/
│               └── example/
│                   └── logprocessing/
│                       ├── LogProcessor.java
│                       ├── LogTask.java
│                       └── MainApp.java
├── logs/
│   └── access_20231010.log
├── target/
│   └── logs/
│       └── access_20231010.log.tar.gz
└── pom.xml

1.`LogTask.java`

`LogTask`类实现`Callable`接口
  用于处理单个日志文件的压缩和移动操作
 
package com.example.logprocessing;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.concurrent.Callable;
import java.util.zip.GZIPOutputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

public class LogTask implements Callable<Boolean> {

    private final File logFile;
    private final Path targetDir;

    public LogTask(File logFile, Path targetDir) {
        this.logFile = logFile;
        this.targetDir = targetDir;
    }

    @Override
    public Boolean call() throws Exception {
        try {
            // 构建压缩文件名
            Path compressedFilePath = targetDir.resolve(logFile.getName() + ".tar.gz");

            // 压缩文件
            compressFile(logFile.toPath(), compressedFilePath);

            // 删除原日志文件
            if (logFile.delete()) {
                System.out.println("Deleted original log file: " + logFile.getAbsolutePath());
                return true;
            } else {
                System.err.println("Failed to delete original log file: " + logFile.getAbsolutePath());
                return false;
            }
        } catch (IOException e) {
            System.err.println("Error processing log file: " + logFile.getAbsolutePath());
            e.printStackTrace();
            return false;
        }
    }

    private void compressFile(Path source, Path target) throws IOException {
        try (ZipOutputStream zos = new ZipOutputStream(new GZIPOutputStream(Files.newOutputStream(target)))) {
            ZipEntry zipEntry = new ZipEntry(source.getFileName().toString());
            zos.putNextEntry(zipEntry);

            byte[] bytes = Files.readAllBytes(source);
            zos.write(bytes, 0, bytes.length);
            zos.closeEntry();
        }
    }
}

2.`LogProcessor.java`

`LogProcessor`类负责管理线程池
 分配任务并监控任务的执行情况
package com.example.logprocessing;

import java.io.File;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arraylist;
import java.util.List;
import java.util.concurrent.*;

public class LogProcessor {

    private final Path logDir;
    private final Path targetDir;
    private final ExecutorService executorService;

    public LogProcessor(String logDirPath, String targetDirPath, int threadPoolSize) {
        this.logDir = Paths.get(logDirPath);
        this.targetDir = Paths.get(targetDirPath);
        this.executorService = Executors.newFixedThreadPool(threadPoolSize);
    }

    public void processLogs() {
        try {
            // 获取前一天的日期
            String yesterday = java.time.LocalDate.now().
			   minusDays(1).format(java.time.format.DateTimeFormatter.ofPattern("yyyyMMdd"));

            // 创建目标目录(如果不存在)
            Files.createDirectories(targetDir);

            // 获取前一天的日志文件
            File[] logFiles = logDir.toFile().
			   listFiles((dir, name) -> name.contains(yesterday));

            if (logFiles == null || logFiles.length == 0) {
                System.out.println("No log files found for " + yesterday);
                return;
            }

            // 提交任务到线程池
            List<Future<Boolean>> futures = new ArrayList<>();
            for (File logFile : logFiles) {
                LogTask task = new LogTask(logFile, targetDir);
                futures.add(executorService.submit(task));
            }

            // 等待所有任务完成
            for (Future<Boolean> future : futures) {
                try {
                    if (future.get()) {
                        System.out.println("Log file processed successfully.");
                    } else {
                        System.err.println("Log file processing failed.");
                    }
                } catch (InterruptedException | ExecutionException e) {
                    System.err.println("Error processing log file.");
                    e.printStackTrace();
                }
            }
        } catch (IOException e) {
            System.err.println("Error creating target directory.");
            e.printStackTrace();
        } finally {
            executorService.shutdown();
        }
    }
}

3.`MainApp.java`

`MainApp` 类是应用程序的入口
 负责初始化`LogProcessor`
 并调用`processLogs`方法

package com.example.logprocessing;

public class MainApp {

    public static void main(String[] args) {
        // 定义日志目录和目标目录
        String logDirPath = "/usr/local/tomcat/DCH_CUBE/logs";
        String targetDirPath = "/data/nasdisk/applogs/DCH_CUBE";

        // 定义线程池大小
        int threadPoolSize = 5;

        // 初始化 LogProcessor
        LogProcessor logProcessor = new LogProcessor(logDirPath, targetDirPath, threadPoolSize);

        // 处理日志文件
        logProcessor.processLogs();
    }
}

4.`pom.xml`(Maven 项目)

使用Maven来管理项目
 可添加以下`pom.xml`文件
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.example</groupId>
    <artifactId>log-processing</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>11</maven.compiler.source>
        <maven.compiler.target>11</maven.compiler.target>
    </properties>

    <dependencies>
        <!-- 添加必要的依赖项 -->
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.1</version>
            </plugin>
        </plugins>
    </build>
</project>

5.配置cron任务

使用 cron 任务每天凌晨运行该脚本。

1.编辑cron任务:
 
    sudo crontab -e
   
2.添加cron任务:
     0 1 * * * /usr/bin/java -cp /path/to/log-processing.jar 
	       com.example.logprocessing.MainApp >> /var/log/log_processing.log 2>&1
  
    - `0 1 * * *`:每天凌晨1点运行脚本。
    - `/usr/bin/java -cp /path/to/log-processing.jar com.example.logprocessing.MainApp`:
	     运行 Java 应用程序。
    - `>> /var/log/log_processing.log 2>&1`:将标准输出和标准错误输出重定向到日志文件。

3.保存并退出:
    - 在 `vi` 或 `nano` 中保存并退出编辑器
版权声明

本文仅代表作者观点,不代表本站立场。
本文系作者授权发表,未经许可,不得转载。

本文链接: https://www.Java265.com/JavaJingYan/202503/17425212128383.html

最近发表

热门文章

好文推荐

Java265.com

https://www.java265.com

站长统计|粤ICP备14097017号-3

Powered By Java265.com信息维护小组

使用手机扫描二维码

关注我们看更多资讯

java爱好者