我们可以在执行程序服务中编写Threadpool执行程序服务吗? 任何人都可以建议如何在并行任务中运行并行任务吗?
假设有10个任务需要并行运行,并且在每个任务中我必须运行100个并行任务。请提出任何建议
ExecutorService executor1 = Executors.newFixedThreadPool(8);
for (int i = 0; i < 8; i++) {
ExecutorService executor2 = Executors.newFixedThreadPool(115);
for (int j = 0; j < 115; j++) {
Runnable worker = new UpdatecheckerTest(Region.getRegion(Regions.US_EAST_1),"");
executor2.execute(worker);
}
}
executor1.shutdown();
这是正确的方法吗?
答案 0 :(得分:0)
这种方法会奏效,但我认为正确的解决方案取决于您未提及的其他事项。
简单案例
如果您要解决的问题非常简单,简短,则不是整个系统的很大部分,那么性能或稳定性就不会有太大的问题。我什至都不用使用线程池,而只使用parallel streams
您的代码可能看起来像这样:
IntStream.range(0,8).().forEach(i -> {
IntStream.range(0,115).parallel().forEach(j -> {
new UpdatecheckerTest(Region.getRegion(Regions.US_EAST_1),"").run();
});
});
整个系统的主要部分
如果您要解决的问题确实是系统的主要部分,那么当我查看您所描述的内容时,我实际上会看到一个大型任务,该任务代表着外循环(i循环)内部发生的事情,并且一个小任务,代表内部循环(j循环)内部正在发生的事情。如果这些任务在您的系统中起主要作用,则您可能希望将这些任务放在自己的类中,以使它们更具可读性,可重用性,并且以后更易于更改。 您的代码可能看起来像这样:
SmallTask.java
import java.text.MessageFormat;
public class SmallTask implements Runnable {
private String identifier;
public SmallTask (String identifier) {
this.identifier = identifier;
}
@Override
public void run() {
System.out.println(String.format(MessageFormat.format("Executing SmallTask with id: {0}", identifier)));
// what ever happens in new UpdatecheckerTest(Region.getRegion(Regions.US_EAST_1),"").run()
}
}
LargeTask.java
import java.text.MessageFormat;
import java.util.stream.IntStream;
public class LargeTask implements Runnable {
private String identifier;
public LargeTask (String identifier) {
this.identifier = identifier;
}
@Override
public void run() {
System.out.println(String.format(MessageFormat.format("Executing LargeTask with id: {0}", identifier)));
IntStream.range(0, 115).parallel().forEach(j -> {
new SmallTask(identifier + "-" + String.valueOf(j)).run();
});
}
}
Main.java
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.stream.IntStream;
public class Main {
public static void main(String[] args) {
IntStream.range(0,8).parallel().forEach(i -> {
new LargeTask(String.valueOf(i)).run();
});
}
}
我什至更进一步地说,大型任务或启动它的原因可能是event driven architecture中的事件,您可以组织系统以拥有各种事件,所有这些事件都可以异步执行。
性能和稳定性很重要
如果此代码在您的系统中非常频繁地运行,那么我将考虑使用线程轮询,该轮询可让您控制正在使用的线程数,以及分配给运行LargeTask的线程与分配给运行SmallTask的线程是否相同。
然后您的代码可能如下所示:
SmallTask.java
import java.text.MessageFormat;
public class SmallTask implements Runnable {
private String identifier;
public SmallTask (String identifier) {
this.identifier = identifier;
}
@Override
public void run() {
System.out.println(String.format(MessageFormat.format("Executing SmallTask with id: {0}", identifier)));
// what ever happens in new UpdatecheckerTest(Region.getRegion(Regions.US_EAST_1),"").run()
}
}
LargeTask.java
import java.text.MessageFormat;
import java.util.stream.IntStream;
public class LargeTask implements Runnable {
private String identifier;
public LargeTask (String identifier) {
this.identifier = identifier;
}
@Override
public void run() {
System.out.println(String.format(MessageFormat.format("Executing LargeTask with id: {0}", identifier)));
IntStream.range(0, 115).forEach(j -> {
TasksExecutor.getSmallTaskExecutor().execute(new SmallTask(identifier + "-" + String.valueOf(j)));
});
}
}
TasksExecutor.java
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class TasksExecutor {
private static ExecutorService largeTasksExecutor = Executors.newFixedThreadPool(8);
private static ExecutorService smallTaskExecutor = Executors.newFixedThreadPool(115);
public static ExecutorService getLargeTaskExecutor () {
return largeTasksExecutor;
}
public static ExecutorService getSmallTaskExecutor () {
return smallTaskExecutor;
}
}
Main.java
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.stream.IntStream;
public class Main {
public static void main(String[] args) {
IntStream.range(0,8).forEach(i -> {
TasksExecutor.getLargeTaskExecutor().execute(new LargeTask(String.valueOf(i)));
});
}
}
如果需要,请不要忘记添加功能来关闭线程池。 也许在每个任务和您要管理的特定线程池之间添加某种依赖注入,这将在以后
为您提供更好的灵活性