精华内容
下载资源
问答
  • linux任务提交

    2015-08-13 21:04:46
    linux下一般用bsub等作为任务提交器,使用起来不方便,每次要配置mpi和openmp的参数。本代码用submit方式,便于配置了并行提交规模。
  • storm 任务提交过程

    千次阅读 2017-09-19 18:08:42
    storm提交topology任务大概分为5个角色,一是:client,二是nimbus,三是zookeeper,四是supervisor,五是worker下面介绍每个角色在任务提交的时候所做的一些操作:1.client:提交topology2.nimbus:这个角色所做的...

    storm提交topology任务大概分为5个角色,一是:client,二是nimbus,三是zookeeper,四是supervisor,五是worker

    下面介绍每个角色在任务提交的时候所做的一些操作:

    1.client:提交topology
    2.nimbus:这个角色所做的操作相对较多,具体如下:
              a.会把提交的jar包放到nimbus所在服务器的nimbus/inbox目录下
              b.submitTopology方法会负责topology的处理;包括检查集群是否有active节点、配置文件是否正确、是否有重复的topology名称、各个bolt/spout名是否使用相同的id等。
              c.建立topology的本地目录,nimbus/stormdist/topology-uuid
                  该目录包括三个文件:
                  stormjar.jar --从nimbus/inbox目录拷贝
                  stormcode.ser --此topology对象的序列化
                  stormconf.ser --此topology的配置文件序列化
              d.nimbus任务分配,根据topology中的定义,给spout/bolt设置task的数目,并分配对应的task-id,最后把分配好的信息写入到zookeeper的../task目录。
              e.nimbus在zookeeper上创建taskbeats目录,要求每个task定时向nimbus汇报
              f.将分配好的任务写入到zookeeper,此时任务提交完毕。zk上的目录为assignments/topology-uuid
              g.将topology信息写入到zookeeper/storms目录
    3.supervisor
              a.定期扫描zookeeper上的storms目录,看看是否有新的任务,有就下载。
              b.删除本地不需要的topology
              c.根据nimbus指定的任务信息启动worker
    4.worker
              a.查看需要执行的任务,根据任务id分辨出spout/bolt任务
              b.计算出所代表的spout/bolt会给哪些task发送信息
              c.执行spout任务或者blot任务
    展开全文
  • Flink任务提交流程和任务调度原理

    千次阅读 2020-01-30 22:14:46
    Flink任务提交后,Client向HDFS上传Flink的Jar包和配置,之后向Yarn ResourceManager提交任务,ResourceManager分配Container资源并通知对应的NodeManager启动ApplicationMaster,ApplicationMaster启动后加载Flink...

    美图欣赏:

     

    一.任务提交流程:

     

     

     

    Flink任务提交后,Client向HDFS上传Flink的Jar包和配置,之后向Yarn ResourceManager提交任务,ResourceManager分配Container资源并通知对应的NodeManager启动ApplicationMaster,ApplicationMaster启动后加载Flink的Jar包和配置构建环境,然后启动JobManager,之后ApplicationMaster向ResourceManager申请资源启动TaskManager,ResourceManager分配Container资源后,由ApplicationMaster通知资源所在节点的NodeManager启动TaskManager,NodeManager加载Flink的Jar包和配置构建环境并启动TaskManager,TaskManager启动后向JobManager发送心跳包,并等待JobManager向其分配任务。

     

     

    二.任务调度原理

     

    1.Program Code我们编写的 Flink 应用程序代码

     

    2.Job ClientJob Client 不是 Flink 程序执行的内部部分,但它是任务执行的起点。 Job Client 负责接受用户的程序代码,然后创建数据流,将数据流提交给 Job Manager 以便进一步执行。 执行完成后,Job Client 将结果返回给用户

     

    3.JobManager主进程(也称为作业管理器)协调和管理程序的执行。 它的主要职责包括安排任务,管理checkpoint ,故障恢复等。机器集群中至少要有一个 master,master 负责调度 task,协调 checkpoints 和容灾,高可用设置的话可以有多个 master,但要保证一个是active, 其他是 standby; Job Manager 包含 Actor system(通信系统)、Scheduler(调度)、Check pointing 三个重要的组件

     

    4.Task Manager从 Job Manager 处接收需要部署的 Task。Task Manager 是在 JVM 中的一个或多个线程中执行任务的工作节点。 任务执行的并行性由每个 Task Manager 上可用的任务槽(task slot)决定。 每个任务代表分配给任务槽的一组资源。 例如,如果 Task Manager 有四个插槽,那么它将为每个插槽分配 25% 的内存。 可以在任务槽中运行一个或多个线程。 同一插槽中的线程共享相同的 JVM。 同一 JVM 中的任务共享 TCP 连接和心跳消息。Task Manager 的一个 Slot 代表一个可用线程,该线程具有固定的内存,注意 Slot 只对内存隔离,没有对 CPU 隔离。默认情况下,Flink 允许子任务共享 Slot,即使它们是不同 task 的 subtask,只要它们来自相同的 job。这种共享可以有更好的资源利用率。

     

     

                                                                                                                                            ————保持饥饿,保持学习

                                                                                                                                                               Jackson_MVP

    展开全文
  • 写给忙人看的Flink任务提交流程

    千次阅读 2020-04-28 20:26:36
    Flink任务提交流程 一、任务提交流程 上篇有简单提到Flink的运行方式有YARN、Mesos、K8s,以及standalone,所以老规矩先根据上篇的内容,先上一个运行图揭示一下当一个应用提交执行时,Flink的各个组件是如何交互...

    Flink任务提交流程

    一、任务提交流程

    上篇有简单提到Flink的运行方式有YARN、Mesos、K8s,以及standalone,所以老规矩先根据上篇的内容,先上一个运行图揭示一下当一个应用提交执行时,Flink的各个组件是如何交互协作的
    在这里插入图片描述
    组件交互流程如上,那么接下来会详细的跟大家聊聊Yarn上运行细节

    二、任务提交流程(YARN)

    先上图:
    在这里插入图片描述
    在Flink任务提交后:

    1. Client向HDFS上传Flink的Jar包和配置
    2. 向Yarn ResourceManager提交任务
    3. ResourceManager分配Container资源并通知对应的NodeManager启动ApplicationMaster
    4. ApplicationMaster启动后加载Flink的Jar包和配置构建环境
    5. 启动JobManager,之后ApplicationMaster向ResourceManager申请资源启动TaskManager
    6. ResourceManager分配Container资源后,由ApplicationMaster通知资源所在节点的NodeManager启动TaskManager,NodeManager加载Flink的Jar包和配置构建环境并启动TaskManager
    7. TaskManager启动后向JobManager发送心跳包,并等待JobManager向其分配任务。

    三、任务调度原理

    在这里插入图片描述
    客户端不是运行时和程序执行的一部分,但它用于准备并发送dataflow(JobGraph)给Master(JobManager),然后,客户端断开连接或者维持连接以等待接收计算结果。
    当 Flink 集群启动后,首先会启动一个 JobManger 和一个或多个的 TaskManager。由 Client 提交任务给 JobManagerJobManager 再调度任务到各个 TaskManager 去执行然后 TaskManager 将心跳和统计信息汇报给 JobManager。TaskManager 之间以流的形式进行数据的传输。上述三者均为独立的 JVM 进程
    Client 为提交 Job 的客户端,可以是运行在任何机器上(与 JobManager 环境连通即可)。提交 Job 后,Client 可以结束进程(Streaming的任务),也可以不结束并等待结果返回。
    JobManager 主要负责调度 Job 并协调 Task 做 checkpoint,职责上很像 Storm 的 Nimbus。从 Client 处接收到 Job 和 JAR 包等资源后,会生成优化后的执行计划,并以 Task 的单元调度到各个 TaskManager 去执行。
    TaskManager 在启动的时候就设置好了槽位数(Slot),每个 slot 能启动一个 Task,Task 为线程。从 JobManager 处接收需要部署的 Task,部署启动后,与自己的上游建立 Netty 连接,接收数据并处理。

    =========================================================
    枯燥无味的文章结束了,这里跟大家简单介绍了Flink的任务提交流程,下一篇会跟大家详细介绍调度流程中的一些小细节!!!

    展开全文
  • Hadoop任务提交过程

    千次阅读 2014-07-21 20:03:13
    Hadoop任务提交分析 分析工具和环境 下载一份hadoop的源码,这里以hadoop-1.1.2为例。本地IDE环境为eclipse,导入整个目录,然后可以在IDE里面看到目录结构了,要分析任务提交过程,需要找到入口代码,很...


    Hadoop任务提交分析


    分析工具和环境

    下载一份hadoop的源码,这里以hadoop-1.1.2为例。本地IDE环境为eclipse,导入整个目录,然后可以在IDE里面看到目录结构了,要分析任务提交过程,需要找到入口代码,很明显,对于熟悉Hadoop应用程序开发的同学来说很容易的知道任务的提交是从job的配置开始的,所以需要这样一份提交Job的代码,在src/examples里面你可以找到一些例子,这里从最简单的wordcount进入去分析提交过程。

    核心的一些类

    Configuration Configuration类是整个框架的配置信息的集合类,里面主要包含了overlaypropertyresources,而主要的方法主要看getset,下面具体看一下这几个变量和方法overlayprivate Properties overlay;,其实overlay是Properties对象,用来存储key-value pair,但是它的主要作用还在于在添加Resource后,保证Resources重载后用户通过set函数设置的属性对会覆盖Resource中相同key的属性对。 properties: 用来存储key-value pair finalParameters:是一个set,用来保存final的配置信息,即不允许覆盖 addResourceObject会添加资源并调用reloadConfiguration,在reloadConfiguration中会清空properties对象和finalParameter,然后下次通过get去读某个属性的时候,会由于properties为null而,重新载入resources,这样资源得到更新,并且,在这之后立马会将overlay里面的内容覆盖进入properties,就是将之前通过set函数设置的属性对去覆盖resource中的默认属性对。

      private synchronized void addResourceObject(Object resource) {
        resources.add(resource);                      // add to resources
        reloadConfiguration();
      }
    
      public synchronized void reloadConfiguration() {
        properties = null;                            // trigger reload
        finalParameters.clear();                      // clear site-limits
      }
    
      public String get(String name) {
        return substituteVars(getProps().getProperty(name)); //这里先是getProps得到properties对象然后调用getProperty得到value,然后通过
                                                                                     //substitudeVars函数去替换value中的${..},其实就是引用变量
      }
    
      private synchronized Properties getProps() {
        if (properties == null) {    //properties为null会重新实例化properties,然后载入资源,并将overlay里面的内容去覆盖properties里面相同key
          properties = new Properties();          //的内容
          loadResources(properties, resources, quietmode);
          if (overlay!= null) {
            properties.putAll(overlay);
            for (Map.Entry<Object,Object> item: overlay.entrySet()) {
              updatingResource.put((String) item.getKey(), UNKNOWN_RESOURCE);
            }
          }
        }
        return properties;
      }
    

    Job

    Job类是hadoop任务配置的对象,继承于JobContext,而他们的构造函数都其实是以Configuration对象作为参数,然后提供了一些设置Job配置信息或者获取Job配置信息的一些函数。

    上述的配置Job信息的函数并不是直接使用了Configuration对象,而是使用了Configuration对象的子类JobConf,JobContext以conf = JobConf(conf)作为内置成员变量。JobConf是在Confguration的基础上提供了Job配置的一些函数

    Job类配置好类以及输入输出等之后,会调用Job.waitforcompletion当然也可以直接调用submit函数,其中waitForCompletion会调用submit然后jobClient.monitorAndPrintJob打印和监视Job的运行进度和情况。

    submit函数分析

    public void submit() throws IOException, InterruptedException, 
                                  ClassNotFoundException {
        ensureState(JobState.DEFINE);
        setUseNewAPI();
    
        // Connect to the JobTracker and submit the job
        connect(); //主要是生成了jobClient对象,而在该对象的初始化过程中,主要生成 了jobSubmitClient的一个动态代理,能够RPC调用
                            //JobTracker中的一些函数(分布式的情况,本地情况先不做分析)
        info = jobClient.submitJobInternal(conf); // 任务提交的过程
        super.setJobID(info.getID());
        state = JobState.RUNNING;
       }
    

    jobClient构造函数分析

    //jobClient的构造函数,设置了conf,然后就调用了init函数
    public JobClient(JobConf conf) throws IOException {
        setConf(conf);
        init(conf);
      }
    
      /**
       * Connect to the default {@link JobTracker}.
       * @param conf the job configuration.
       * @throws IOException
       */
      public void init(JobConf conf) throws IOException {
        String tracker = conf.get("mapred.job.tracker", "local");
        tasklogtimeout = conf.getInt(
          TASKLOG_PULL_TIMEOUT_KEY, DEFAULT_TASKLOG_TIMEOUT);
        this.ugi = UserGroupInformation.getCurrentUser();
        if ("local".equals(tracker)) {
          conf.setNumMapTasks(1);
          this.jobSubmitClient = new LocalJobRunner(conf); //本地模式下,会生成一个LocalJobRunner对象
        } else {
          this.rpcJobSubmitClient = 
              createRPCProxy(JobTracker.getAddress(conf), conf); // 分布式模式下,会生成了一个RPC代理
          this.jobSubmitClient = createProxy(this.rpcJobSubmitClient, conf); //对这个代理再次封装了一下,其实里面主要是增加了retry的一些代码
        }        
      }
    

    jobClient.submitJobInternal函数分析

    public 
      RunningJob submitJobInternal(final JobConf job
                                   ) throws FileNotFoundException, 
                                            ClassNotFoundException,
                                            InterruptedException,
                                            IOException {
        /*
         * configure the command line options correctly on the submitting dfs
         */
        return ugi.doAs(new PrivilegedExceptionAction<RunningJob>() {
          public RunningJob run() throws FileNotFoundException, 
          ClassNotFoundException,
          InterruptedException,
          IOException{
            JobConf jobCopy = job;
            Path jobStagingArea = JobSubmissionFiles.getStagingDir(JobClient.this,
                jobCopy); //获得任务提交的目录,其实是作为参数的JobClient去通过RPC从JobTracker那里获取得到jobStagingArea
                                // ${hadoop.tmp.dir}/mapred/staging/user-name/.staging目录
            JobID jobId = jobSubmitClient.getNewJobId();  //从JobTracker那里获得分配的jobid
            Path submitJobDir = new Path(jobStagingArea, jobId.toString()); //submitJobDir = ${jobStagingArea}/job-id
            jobCopy.set("mapreduce.job.dir", submitJobDir.toString());
            JobStatus status = null;
            try {
              populateTokenCache(jobCopy, jobCopy.getCredentials());
    
              copyAndConfigureFiles(jobCopy, submitJobDir); // 这个函数主要是负责处理通过参数--libjars,--archives,--files引入的jar包,以及要使用分布式缓存的文件和archive,并且将job.jar也拷贝到分布式文件系统上
    
              // get delegation token for the dir
              TokenCache.obtainTokensForNamenodes(jobCopy.getCredentials(),
                                                  new Path [] {submitJobDir},
                                                  jobCopy);
    
              Path submitJobFile = JobSubmissionFiles.getJobConfPath(submitJobDir);
              int reduces = jobCopy.getNumReduceTasks();
              InetAddress ip = InetAddress.getLocalHost();
              if (ip != null) {
                job.setJobSubmitHostAddress(ip.getHostAddress());
                job.setJobSubmitHostName(ip.getHostName());
              }
              JobContext context = new JobContext(jobCopy, jobId);
    
            //检查output,如果已经存在则会抛出异常
              // Check the output specification
              if (reduces == 0 ? jobCopy.getUseNewMapper() : 
                jobCopy.getUseNewReducer()) {
                org.apache.hadoop.mapreduce.OutputFormat<?,?> output =
                  ReflectionUtils.newInstance(context.getOutputFormatClass(),
                      jobCopy);
                output.checkOutputSpecs(context);
              } else {
                jobCopy.getOutputFormat().checkOutputSpecs(fs, jobCopy);
              }
    
              jobCopy = (JobConf)context.getConfiguration();
    
            //利用设置好的inputformat的来对输入进行分片,然后将分片写入到job.split中,然后也会将分片的元信息写入到job.splitmetainfo中
            //
              // Create the splits for the job
              FileSystem fs = submitJobDir.getFileSystem(jobCopy);
              LOG.debug("Creating splits at " + fs.makeQualified(submitJobDir));
              int maps = writeSplits(context, submitJobDir);
              jobCopy.setNumMapTasks(maps);
    
              // write "queue admins of the queue to which job is being submitted"
              // to job file.
              String queue = jobCopy.getQueueName();
              AccessControlList acl = jobSubmitClient.getQueueAdmins(queue);
              jobCopy.set(QueueManager.toFullPropertyName(queue,
                  QueueACL.ADMINISTER_JOBS.getAclName()), acl.getACLString());
    
    
                //将job配置相关的信息写入到job.xml中
              // Write job file to JobTracker's fs        
              FSDataOutputStream out = 
                FileSystem.create(fs, submitJobFile,
                    new FsPermission(JobSubmissionFiles.JOB_FILE_PERMISSION));
    
              try {
                jobCopy.writeXml(out);  //正式写入
              } finally {
                out.close();
              }
              //
              // Now, actually submit the job (using the submit name)
              //
              printTokens(jobId, jobCopy.getCredentials());
              status = jobSubmitClient.submitJob(
                  jobId, submitJobDir.toString(), jobCopy.getCredentials()); //通过RPC提交任务给JobTracker,让其去管理任务,在JobTrakcker的
                                                                                                    //subnitJob里面会实例化JobInProgress并保存在一个jobs的Map<jobID,JobInProgress>的map里面
              JobProfile prof = jobSubmitClient.getJobProfile(jobId); //获得任务的概要信息,主要包括了jobname,jobid,提交的队列名,job配置信息的路径,用户,web接口的url等
              if (status != null && prof != null) {
                return new NetworkedJob(status, prof, jobSubmitClient); //对status,prof,以及jobSubmitClient的封装,主要用来可以查询进度信息和profile信息。而status里面提供了getMapProgress和setMapProgress类型的接口函数
              } else {
                throw new IOException("Could not launch job");
              }
            } finally {
              if (status == null) {
                LOG.info("Cleaning up the staging area " + submitJobDir);
                if (fs != null && submitJobDir != null)
                  fs.delete(submitJobDir, true);
              }
            }
          }
        });
      }
    

    JobClient

    从上面的一些代码也可以看出真正提交Job是在JobClient做的,它主要处理了一些参数像libjars files archives把他们指定的文件拷贝到HDFS的submitJobDir,然后把JOb的配置信息job.xml , 分片信息以及job.jar也都拷贝到HDFS上。然后利用jobClient里面的一个代理类jobSubmitClient来提交任务,其实就是一个RPC请求,向JObTracker发送请求,然后返回的是一个JobStatus类型的对象,该对象可以查询map reduce进度等。


    下一篇讲一下JObTracker相关

    展开全文
  • Spark任务提交执行全流程详解

    千次阅读 2018-11-15 17:57:52
    任务提交执行流程 ** Spark任务的本质是对我们编写的RDD的依赖关系切分成一个个Stage,将Stage按照分区分批次的生成TaskSet发送到Executor进行任务的执行 Spark任务分两种: 1、shuffleMapTask:shuffle之后的task 2...
  • Storm任务提交过程及目录树介绍

    千次阅读 2018-04-06 22:37:12
    对于任何一个组件来说,了解它相关的任务提交的过程是非常有必要的(毕竟生产中遇到一些Bug时,你如果知道内部执行的过程,那么会对问题的解决会有很大的帮助)。除此之外还会对Storm相关的目录树进行一个简单的介绍...
  • YARN的任务提交流程简述及图解

    千次阅读 2018-11-10 09:27:14
    #YARN的任务提交流程简述及图解 1,Client向ResourceManager发出请求,提交程序,(ResourceManager中有Scheduler调度器和ApplicationsManager应用程序管理器 2,ResourceManager向Scheduler返回一个ApplicationID...
  • flink任务提交

    万次阅读 2018-08-07 11:59:18
    flink安装启动后,默认端口为8081。 ...可以看到正在运行的任务及状态。 ...若要提交新的任务,点击“Submit new Job” -- “Add New+”,上传编译好的jar包工程 ...点击新上传的jar包,可进行...提交后可看到任务运行及...
  • Flink任务提交流程(Standalone和Yarn)

    千次阅读 2019-10-23 10:16:02
    文章目录1、任务提交流程(Standalone)2、任务提交流程(Yarn) 1、任务提交流程(Standalone) 1)App程序通过rest接口提交给Dispatcher。 2)Dispatcher把JobManager进程启动,把应用交给JobManager。 3)...
  • 任务提交方式及示例继续:Flink1.9.0任务提交源码阅读(二):入口类CliFrontendFlink1.9.0任务提交源码阅读(三):Job提交--run() PS:在工作中有个需求:使用java API的方式提交flink job 到yarn上,有yarn负责...
  • task来源于stage,所有本文先从stage提交开始讲解task任务提交。   架构图: Standalone模式提交运行流程图: 首先写一个WordCount代码(这个代码,为了观察多个suffle操作,我写了两个reducebykey 函数) ...
  • 使用Semaphore控制线程池任务提交的速率 欢迎关注作者博客 简书传送门 介绍   当线程池的工作队列被填满后,如果没有预定义的饱和策略来阻塞任务的执行,则可以通过信号量Semaphore来限制任务的到达率。...
  • 任务提交后,client向hdfs上传flink的jar包以及配置 向Yarn的ResourceManager提交任务 ResourceManager分配Container资源并通知对应的NodeManager启动ApplicationMaster ApplicationMaster启动后加载flink的jar包和...
  • Flink任务提交模式

    千次阅读 2018-04-12 13:15:27
    local模式本地运行,不需要集群环境IDE开发时,local模式方便本地测试standalone需要搭建flink集群提交命令flink run -m artemis-02:6123 -c ...
  • YARN任务提交流程

    千次阅读 2017-07-03 10:01:47
    yarn取代了以前hadoop中jobtracker(后面简写JT)的角色,因为以前JT的 任务过重,负责任务的调度、跟踪、失败重启等过程,而且只能运行mapreduce作业,不支持其他编程模式,这也限制了JT使用范围,而yarn应运而 生...
  • spark任务提交的四个阶段 1、构建DAG 用户提交的job将首先被转换成一系列RDD并通过RDD之间的依赖关系构建DAG,然后将DAG提交到调度系统; 一个RDD描述了数据计算过程中的一个环节,而一个DAG包含多个RDD,描述了...
  • Standalone模式提交运行流程图:     首先写一个WordCount代码(这个代码,为了观察多个stage操作,我写了两个reducebykey 函数) 源代码:   直接执行代码,查看spark执行程序时,将代码划分stage生成...
  • 今天主要分析一下Spark源码中提交任务脚本的处理逻辑,从spark-submit一步步深入进去看看任务提交的整体流程,首先看一下整体的流程概要图: 接下来按照图中结构出发一步步看源码:spark-submit#!/usr/bin/env bash#...
  • spark任务提交 spark目前提供python shell和scala shell两种交互式命令行运行Python Shell ./bin/pyspark 运行Scala Shell./bin/spark-shell 比如用户使用spark-shell或是pyspark脚本启动Spark应用程序,伴随应用...
  • Spark任务提交后,任务一直处于Accept状态,无法正常运行。Driver端提示executor memory超限。 原因分析 FusionInsight集群中,Spark任务运行在Yarn的资源管理框架下,由Yarn来负责资源的调度管理,Yarn在接收...
  • 作为一个执行服务ExecutorService的实例,ThreadPoolExecutor的首要任务当然是提交任务进行处理,那么,在任务提交时,ThreadPoolExecutor的处理流程是怎样的?它是一味的开启线程进行处理,还是有一套完整的逻辑来...
  • spark版本号:1.4.1 spark源码分析目的是在解读源码的过程中...Standalone集群启动及任务提交过程详解 正常启动及job提交过程如下: 1. 启动master 2. 启动worker 3. 客户端提交application到master 4. maste
  • MapReduce框架以及Hive任务提交详解

    千次阅读 2019-11-01 16:45:30
    在切Hive任务到Spark的时候,发现Spark在处理只有Hive元数据而HDFS文件块丢失的任务时,会抛HDFS的异常InvalidInputException,而Hive在这种情况下不受影响。 因此,就去找Hive在处理只有元数据的空表时做的优化。...
  • 利用 Python 实现多线程多任务提交、运行 可先参考博客文章:https://segmentfault.com/a/1190000000414339
  • Flink:任务提交详细流程

    千次阅读 2020-03-27 22:33:15
    1.Flink多种提交方式对比 1.1 local模式 1.1.1 纯粹的local模式运行 1.1.2 local使用remote的方式运行 1.1.3 本地提交到remote集群 1.2 standalone模式 1.3 yarn模式 1.3.1 yarn-session 1.3.2 yarn-cluster 2.flink...
  • ThreadPoolExecutor参数解析 之前学习线程池,发现线程池大致有四种创建方法: ...newScheduledThreadPool 创建一个可周期性调度任务的线程池 public static ExecutorService newFixedThreadPool(int nThreads

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 439,126
精华内容 175,650
关键字:

任务提交