Java异步执行将CPU提高100%

Java异步执行将CPU提高100%,java,spring,Java,Spring,导言: 我开发了一个类,它可以接受大量的任务,并行执行它们,并等待特定时间的结果。如果某些任务在给定的超时时间内未能完成,它将中断整个执行并仅返回可用的结果 问题: 开始时一切正常,但一段时间后CPU使用率增加到100%,应用程序显然无法响应 你能帮我找到一个问题或提出更好的解决方案吗?我怎样才能达到同样的目标 代码: TaskService.java public abstract class TaskService { private static final org.slf4j.

导言:

我开发了一个类,它可以接受大量的
任务
,并行执行它们,并等待特定时间的结果。如果某些任务在给定的超时时间内未能完成,它将中断整个执行并仅返回可用的结果

问题:

开始时一切正常,但一段时间后CPU使用率增加到100%,应用程序显然无法响应

你能帮我找到一个问题或提出更好的解决方案吗?我怎样才能达到同样的目标

代码:

TaskService.java

public abstract class TaskService {

    private static final org.slf4j.Logger InfoLogger = LoggerFactory.getLogger("InfoLogger");
    private static final org.slf4j.Logger ErrorLogger = LoggerFactory.getLogger("ErrorLogger");

    @Autowired
    private TimeLimiter timeLimiter;


    public List<TaskResult> execute(TaskType taskType, TimeUnit timeUnit, long timeout, final Task... tasks){

        final List<TaskResult> taskResultsStorage = new ArrayList<>();
        try {
            timeLimiter.callWithTimeout(new Callable<List<TaskResult>>() {
                @Override
                public List<TaskResult> call() throws Exception {
                    return run(taskResultsStorage, tasks);
                }
            }, timeout, timeUnit, true);

        } catch (UncheckedTimeoutException e) {
            String errorMsg = String.format("Time out of [%s] [%s] has been exceeded for task type:[%s]", timeout, timeUnit.name(), taskType.name());
            ErrorLogger.error(errorMsg, e);
        } catch (Exception e) {
            String errorMsg = String.format("Unexpected error for task type:[%s]", taskType.name());
            ErrorLogger.error(errorMsg, e);
        }

        return taskResultsStorage;
    }



    protected abstract List<TaskResult> run(List<TaskResult> taskResults,Task... tasks) throws ExecutionException, InterruptedException;

}
public class AsynchronousTaskService extends TaskService {


    private CompletionService<TaskResult> completionService;

    public AsynchronousTaskService(ThreadExecutorFactory threadExecutorFactory){
        this.completionService = new ExecutorCompletionService<TaskResult>(threadExecutorFactory.getExecutor());
    }


    @Override
    protected List<TaskResult> run(List<TaskResult> resultStorage, Task... tasks) throws ExecutionException, InterruptedException {

        List<Future<TaskResult>> futureResults = executeTask(tasks);
        awaitForResults(futureResults, resultStorage);
        return resultStorage;
    }


    private List<Future<TaskResult>> executeTask(Task... tasks){

        List<Future<TaskResult>> futureTaskResults = new ArrayList<>();
        if(tasks!=null) {
            for (Task task : tasks) {
                if (task != null) {
                    futureTaskResults.add(completionService.submit(task));
                }
            }
        }
        return futureTaskResults;
    }

    private void awaitForResults(List<Future<TaskResult>> futureResults, List<TaskResult> resultStorage) throws ExecutionException, InterruptedException {

        int submittedTasks = futureResults.size();
        int taskCompleted = 0;
        if(futureResults != null){
            while(taskCompleted < submittedTasks){
                Iterator<Future<TaskResult>> it = futureResults.iterator();
                while(it.hasNext()){
                    Future<TaskResult> processingTask = it.next();
                    if(processingTask.isDone()){
                        TaskResult taskResult = processingTask.get();
                        resultStorage.add(taskResult);
                        it.remove();
                        taskCompleted++;
                    }
                }
            }
        }
    }
}
@Component
public class ThreadExecutorFactory {


    private int THREAD_LIMIT = 100;
    private final Executor executor;

    public ThreadExecutorFactory() {
        executor = Executors.newFixedThreadPool(THREAD_LIMIT,
                new ThreadFactory() {
                    public Thread newThread(Runnable r) {
                        Thread t = new Thread(r);
                        t.setDaemon(true);
                        return t;
                    }
                });
    }

    public Executor getExecutor() {
        return executor;
    }
}
public abstract class Task<T extends TaskResult> implements Callable<T> {
}
public abstract class TaskResult {
}
Task.java

public abstract class TaskService {

    private static final org.slf4j.Logger InfoLogger = LoggerFactory.getLogger("InfoLogger");
    private static final org.slf4j.Logger ErrorLogger = LoggerFactory.getLogger("ErrorLogger");

    @Autowired
    private TimeLimiter timeLimiter;


    public List<TaskResult> execute(TaskType taskType, TimeUnit timeUnit, long timeout, final Task... tasks){

        final List<TaskResult> taskResultsStorage = new ArrayList<>();
        try {
            timeLimiter.callWithTimeout(new Callable<List<TaskResult>>() {
                @Override
                public List<TaskResult> call() throws Exception {
                    return run(taskResultsStorage, tasks);
                }
            }, timeout, timeUnit, true);

        } catch (UncheckedTimeoutException e) {
            String errorMsg = String.format("Time out of [%s] [%s] has been exceeded for task type:[%s]", timeout, timeUnit.name(), taskType.name());
            ErrorLogger.error(errorMsg, e);
        } catch (Exception e) {
            String errorMsg = String.format("Unexpected error for task type:[%s]", taskType.name());
            ErrorLogger.error(errorMsg, e);
        }

        return taskResultsStorage;
    }



    protected abstract List<TaskResult> run(List<TaskResult> taskResults,Task... tasks) throws ExecutionException, InterruptedException;

}
public class AsynchronousTaskService extends TaskService {


    private CompletionService<TaskResult> completionService;

    public AsynchronousTaskService(ThreadExecutorFactory threadExecutorFactory){
        this.completionService = new ExecutorCompletionService<TaskResult>(threadExecutorFactory.getExecutor());
    }


    @Override
    protected List<TaskResult> run(List<TaskResult> resultStorage, Task... tasks) throws ExecutionException, InterruptedException {

        List<Future<TaskResult>> futureResults = executeTask(tasks);
        awaitForResults(futureResults, resultStorage);
        return resultStorage;
    }


    private List<Future<TaskResult>> executeTask(Task... tasks){

        List<Future<TaskResult>> futureTaskResults = new ArrayList<>();
        if(tasks!=null) {
            for (Task task : tasks) {
                if (task != null) {
                    futureTaskResults.add(completionService.submit(task));
                }
            }
        }
        return futureTaskResults;
    }

    private void awaitForResults(List<Future<TaskResult>> futureResults, List<TaskResult> resultStorage) throws ExecutionException, InterruptedException {

        int submittedTasks = futureResults.size();
        int taskCompleted = 0;
        if(futureResults != null){
            while(taskCompleted < submittedTasks){
                Iterator<Future<TaskResult>> it = futureResults.iterator();
                while(it.hasNext()){
                    Future<TaskResult> processingTask = it.next();
                    if(processingTask.isDone()){
                        TaskResult taskResult = processingTask.get();
                        resultStorage.add(taskResult);
                        it.remove();
                        taskCompleted++;
                    }
                }
            }
        }
    }
}
@Component
public class ThreadExecutorFactory {


    private int THREAD_LIMIT = 100;
    private final Executor executor;

    public ThreadExecutorFactory() {
        executor = Executors.newFixedThreadPool(THREAD_LIMIT,
                new ThreadFactory() {
                    public Thread newThread(Runnable r) {
                        Thread t = new Thread(r);
                        t.setDaemon(true);
                        return t;
                    }
                });
    }

    public Executor getExecutor() {
        return executor;
    }
}
public abstract class Task<T extends TaskResult> implements Callable<T> {
}
public abstract class TaskResult {
}

您的方法
waitforresults
包含一个忙循环:

while(taskCompleted < submittedTasks){
    ...
    while(it.hasNext()){
这是快速和肮脏的,但将有助于解决100%的cpu。或者,更多的工作是实现一些信令机制,以便循环等待来自某个已完成任务的信号


正如其他人所建议的,如果100个线程都是cpu受限的,那么它们可能没有意义,但我怀疑这是否真的是您的问题。

您是否尝试过降低线程限制?例如,系统的内核数量(例如,使用
Runtime.getRuntime().availableProcessor()
)?在这个问题上,线程数超过处理器(或2*处理器用于超线程CPU)将显著降低性能。这可能不是你的问题,但100个线程是一个坏主意。对于你的评论,伙计们,我会尽量减少池中的线程数量。