我有一个像IJob这样的工作界面:
public interface IJob {
public void execute();
}
在我的应用程序中,我有多个实现此接口的类,如IJob1和IJob2:
public class IJob1 implements IJob{
@Override
public void execute(){
System.out.println("IJob1\n");
}
}
public class IJob2 implements IJob{
@Override
public void execute(){
System.out.println("IJob2\n");
}
}
由于要运行的作业数量稳步增加,我想创建一个新作业,它接受一个IJob实例列表并并行运行它们。新实现用于并行运行作业的线程数量应该是可配置的。如果其中一个作业抛出异常,那么所有其他当前正在运行的作业也应该停止,而execute()方法应该将异常传递给调用者。
我写了这个,但我无法运行工作并检查是否有错误:
import java.util.LinkedList;
public class WorkQueue
{
private final int nThreads;
private final IJob[] threads;
private final LinkedList queue;
public WorkQueue(int nThreads)
{
this.nThreads = nThreads;
queue = new LinkedList();
threads = new IJob[nThreads];
for (int i=0; i<nThreads; i++) {
threads[i] = new IJob();
threads[i].execute();
}
}
public void execute(Runnable r) {
synchronized(queue) {
queue.addLast(r);
queue.notify();
}
}
private class PoolWorker extends Thread {
public void run() {
Runnable r;
while (true) {
synchronized(queue) {
while (queue.isEmpty()) {
try
{
queue.wait();
}
catch (InterruptedException ignored)
{
}
}
r = (Runnable) queue.removeFirst();
}
// If we don't catch RuntimeException,
// the pool could leak threads
try {
r.run();
}
catch (RuntimeException e) {
// You might want to log something here
}
}
}
}
}
请你帮我一些帮助吗? 非常感谢你。
答案 0 :(得分:5)
我建议使用托管线程池。典型的模式是使用Java Executors来获取ExecutorService。 ExecutorService通常使用线程池和作业队列来实现。在ExecutorService上,有一些方法,如shutdownNow()
,&#34;尝试停止所有正在执行的任务&#34;。这听起来像你想要做的。
实施例,
List<Callable<Result>> tasks = new ArrayList<>();
for (final Object job: jobs) {
final Callable<Result> task = new Callable<Result>() {
@Override
public Result call() throws Exception {
// Do job here
return result;
}
};
tasks.add(task);
}
final numOfThreads = 20;
final ExecutorService executor = Executors.newFixedThreadPool(numOfThreads);
try {
executor.invokeAll(tasks);
} finally {
executor.shutdownNow();
}
答案 1 :(得分:4)
我想创建一个新作业,它接受一个IJob实例列表并并行运行它们。新实现用于并行运行作业的线程数量应该是可配置的。如果其中一个作业抛出异常,那么所有其他当前正在运行的作业也应该停止,而execute()方法应该将异常传递给调用者。
这是使用parallelStream()将使您的生活更简单的地方。你可以做到
list.parallelStream().
.forEach(IJob::execute);
您可能会发现根本不需要框架,您可以将此代码合并到调用者中。 e.g。
Map<String, T> map = dataSet.parallelStream()
.map(t -> t.transform1())
.filter(t -> t.isGood())
.collect(Collectors.groupingByConcurrent(t.getKey()));