【发布时间】:2021-04-20 16:20:28
【问题描述】:
我需要重构代码以查看它是否可以帮助我解决“无法打开 Hibernate Session 进行事务”。我目前正在尝试简化代码中处理线程的方式。
现有代码如下所示。让我们称之为“代码 A”:
if (!CollectionUtils.isEmpty(dailyReportProjectList)) {
for (ProjectEntity project : dailyReportProjectList) {
Thread.sleep(2000);
new Thread(() -> {
try {
// Implementation Logic
if (isConfig == true) {
// Generating Daily Report
if (dailyRep != null) {
LOG.info(
"============start of daily report mail for zone : " + zone + ", newZone : "
+ newZone + " for date : " + currOrPrevDay + "===============");
new Thread(() -> {
try {
//genericController;
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
}
} else {
//"All 4 default reports for site : " + project.getId() + ", empId:" + project.getEmployerId());
}
}
}
LOG.info("End of generateReportByZone >> zone : " + zone);
} catch (Exception e2) {
e2.printStackTrace();
}
}
}).start();
}
}
为了简化这一点,我决定继续使用 Executor Service。我提到了一些例子,我对使用 service.submit() 或 service.execute() 感到困惑。 我没有从下面的代码中看到我想要的好处。你能帮我找出这个方法的任何问题吗?
编辑:基于 cmets,我已经简化了上面的现有代码。线程内部有一个线程,我觉得没有太大的成就。有这样的实现可以吗?
我打算做以下事情:
-
不要传递线程,而是作为 for 循环中的参数,创建一个单独的类并让它实现可运行。
public class ReportProcessor implements Runnable { private int id; public ReportProcessor (int id){ this.id = id; } public void run(){ try { String currOrPrevDay = new String(); ...// write the code in the try element of 'code A' here onwards -
在“代码 A”执行程序中。提交新创建的类
for (i = 0; i < dailyReportProjectList.length; i ++){ service.submit(new ReportProcessor(i)); }
但是,如果我将逻辑分离到一个新类中,我如何满足现有规定的“代码 A”所需的依赖关系。我正在尝试在本教程https://www.youtube.com/watch?v=KUdro0G1BV4&t=325s
的基础上为我的执行器服务建模【问题讨论】:
-
您的帖子太大且难以阅读。首先用几个更简单、更有意义的调用重构这个怪物。
-
嗨,marc,我肯定会尝试这样做,但您能否帮助我确认以这种方式调用线程是正确的。如果需要,我将使用虚拟值简化代码。
-
将示例代码精简到解决您的特定技术问题所需的绝对最低限度。 MCVE
-
永远不要将线程传递给这样的执行程序。传入的线程被视为可运行的,实际的操作系统线程未被使用。这是在浪费资源。
-
执行器服务的全部意义在于它会根据需要为您创建线程。相反,您应该将可调用对象或可运行对象传递给执行程序。
标签: java multithreading threadpool executorservice