gpt4 book ai didi

java - 为什么我的多线程应用程序被暂停?

转载 作者:行者123 更新时间:2023-11-30 04:36:00 25 4
gpt4 key购买 nike

我的多线程应用程序有一个创建多个线程的主类。主类在启动一些线程后将等待。我创建的可运行类将通过调用 Web 服务获取文件列表、获取文件和删除文件。线程完成后会通知主类再次运行。我的问题是它可以工作一段时间,但可能在一小时左右后,它会从我在日志中看到的输出到达 run 方法的底部,就是这样。 Java 进程仍在运行,但根据我在日志中看到的内容,它没有执行任何操作。

主要类方法:

主要方法

while (true) {

// Removed the code here, it was just calling a web service to get a list of companies

// Removed code here was creating the threads and calling the start method for threads

mainClassInstance.waitMainClass();
}

public final synchronized void waitMainClass() throws Exception {
// synchronized (this) {
this.wait();
// }
}

public final synchronized void notifyMainClass() throws Exception {
// synchronized (this) {
this.notify();
// }
}

我原本是在实例上进行同步,但改为方法。 Web 服务日志或客户端日志中也没有记录任何错误。我的假设是我的等待和通知错误,或者我丢失了一些信息。

可运行线程代码:

在run方法结束时

// This is a class member variable in the runnable thread class
mainClassInstance.notifyMainClass();

我之所以执行等待和通知过程,是因为我不希望主类运行,除非需要创建另一个线程。

主类的目的是生成线程。该类有一个无限循环来永远运行创建和完成线程。

无限循环的目的是不断更新公司列表。

最佳答案

我建议从棘手的等待/通知转移到 Java 平台中的高级并发工具之一。 ExecutorService可能提供您需要的开箱即用的功能。 (CountDownLatch也可以使用,但它更多的是管道)让我们尝试使用您的代码作为模板来绘制一个示例:

ExecutorService execSvc = Executors.newFixedThreadPool(THREAD_COUNT);

while (true) {

// Removed the code here, it was just calling a web service to get a list of companies
List<FileProcessingTask> tasks = new ArrayList<FileProcessingTask>();
for (Company comp:companyList) {
tasks.add(new FileProcessingTask(comp));
}
List<Future<FileProcessingTask>> results = execSvc.invokeAll(tasks); // This call will block until all tasks are executed.
//foreach Future<FileProcessingTask> in results: check result
}

class FileProcessingTask implements Callable<FileResult> { // just like runnable but you can return a value -> very useful to gather results after the multi-threaded execution
FileResult call() {...}
}

--------评论后编辑------

如果您的 getCompanies() 调用可以立即为您提供所有公司,并且无需在处理时连续检查该列表,您可以通过首先创建所有工作项并提交它们来简化流程一次性发送给执行者服务。

List<FileProcessingTask> tasks = new ArrayList<FileProcessingTask>();
for (Company comp:companyList) {
tasks.add(new FileProcessingTask(comp));
}

需要理解的重要一点是 executorService 将使用提供的集合作为要执行的任务的内部队列。它获取第一个任务,将其交给池中的线程,收集结果,将结果放入结果集合中,然后获取队列中的下一个任务。

如果您没有生产者/消费者场景(cfr 注释),即在执行(消耗)任务的同时生成新工作,那么,这种方法应该足以并行化多个任务之间的处理工作。以简单的方式计算线程数。

如果您有其他要求,为什么新工作的查找应与工作处理交错进行,则应在问题中明确说明。

关于java - 为什么我的多线程应用程序被暂停?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13518567/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com