命令行启动的线程模型优化

博客内容介绍了对一个基于Java的命令行线程模型进行优化的过程,涉及到CPU核心池的使用、线程绑定、阻塞队列和线程池的调度。作者详细解析了CommandExecutor如何通过CommandThread执行命令,并探讨了如何减少线程层级以提升效率。
摘要由CSDN通过智能技术生成

熟悉代码

腾哥给了些任务
任务
通读完judger的核心代码,跟黄学长联系修改完OLE,就开始尝试研究命令行启动的线程模型优化。(因为judger的代码在github上是公开的,so我这里就直接贴腾哥的代码啦)

@author:张腾学长
public class CommandExecutor {
   

    // CPU 池
    private final Queue<Integer> cpuPool;

    // 线程池
    private final CompletionService<CommandExecuteResult> threadPool;

    /**
     * @Description 提交一个异步任务
     **/
    public void submit(Command command) {
   
        threadPool.submit(new CommandThread(command, cpuPool));
    }

    /**
     * @Description 获取一个任务的执行结果,顺序任意取决于任务完成顺序
     * @return cn.edu.sdu.qd.oj.judger.dto.CommandExecResult
     **/
    public CommandExecuteResult take() throws InterruptedException, ExecutionException {
   
        return threadPool.take().get();
    }

    public CommandExecutor() {
   
        // 初始化 cpu 池,从本机配置文件中读取运行的核心都有哪些
        cpuPool = new LinkedBlockingDeque<>(CpuConfig.getCpuSet());
        // 初始化线程池
        threadPool = new ExecutorCompletionService<>(new ThreadPoolExecutor(
                cpuPool.size(),
                cpuPool.size(),
                0,
                TimeUnit.SECONDS,
                new LinkedBlockingQueue<>(1024),
                new ThreadPoolExecutor.CallerRunsPolicy())
        );
        log.info("init threadPool {}", cpuPool.size());
    }


    private static class CommandThread implements Callable<CommandExecuteResult> {
   

        private final Command command;

        private final Queue<Integer> cpuPool;

        public CommandThread(Command command, Queue<Integer> cpuPool) {
   
            this.command = command;
            this.cpuPool = cpuPool;
        }

        @Override
        public CommandExecuteResult call() throws Exception {
   
            log.info("exec {}", command.toString());
            Integer coreNo = null;
            try {
   
                coreNo = cpuPool.poll();
                log.info("cpu consume {}", coreNo);
                return command.run(coreNo != null ? coreNo : 0);
            } finally {
   
                log.info("cpu release {}", coreNo);
                if (coreNo != null) {
   
                    cpuPool.offer(coreNo);
                }
            }
        }
    }
}

cpupool是cpu核心池,通过读取本机的cpu配置文件获得,是一些离散的数字,所以用双端队列储存,从头取,运行结束放回到队伍尾部。

@author:张腾学长
public class SandboxRunner {
   

    private static final String SANDBOX_PATH = "/usr/bin/sandbox";

    public static SandboxResultDTO run(String cwd, Argument... args) throws SystemErrorException {
   
        return run(CpuConfig.getCpuSet().iterator().next(),cwd, args);
    }

    public static SandboxResultDTO run(int coreNo, String cwd, Argument... args) throws SystemErrorException {
   
        List
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值