粉丝4.5万获赞28.2万

哈喽,今天给大家分享多线程实现百万导出到 excel, 由原来的五十秒呢优化到十一秒, 比如说像现在这个结果多线称导出呢,我这边是分 shit 页进行导出的,那每个 shit 页呢大概是一万条数据,那我这边呢有一百个 shit 页,然后就有一百万条数据,那我们来看一下这段代码, 那前面呢都是一些通用的设置,我们从这边开始看,那这边呢是查询他的一个总数据量,然后每页呢是一万个,然后我们这边用 easy excel 创建了一个操作类, 然后这边创建了一个 compatable future 集合,我们在这边呢分批去查询数据库,然后构造不同的社贴页,最终呢用我们的操作类啊把我们的数据呢导出到我们的社贴页中,然后这边呢我加了一个同步锁,因为我们的多线程在访问共享变量的时候呢, 如果你不加锁的话会有问题,那因为我这边锁的力度呢比较少,所以我的查询是可以并发去执行的。那我们把这样的义薄任务啊放到我们的县城池中,最终放到我们这样的集合中,并且呢我们让所有的义薄任务呢执行完,最终我们刷新流,并且关闭流。 好代码呢也是比较简单的,如果说大家想要这样的一个 demo 的话呢,可以到这来这,然后呢给他去发一个消息,像这样就可以拿到我们的 demo。 好,今天的一个分享呢就到这。

哈喽,今天给大家分享多线程实现百万级数据导出到 excel, 那在大数据量导出到文件呢?我们首先需要考虑的是内存溢出的场景,数据库读取数据到内存中呢,将数据写入到 excel, 会进行大量的一个 io 操作。我们先来看这段代码, 那比如这边有一个 tot 参数,比如说我想要导入十万条的一个记录,然后 limit 呢?比如说是五千条,那前面这几个呢,都是一些常规的一个设置。我们来看一下这一行代码,我们点进去,然后看时限类, 然后比如说这边是十万条,我们 limit 是五千,那这一行代码呢?就是说,比如我们计算出多少页几个循环次数,比如说我看的是五四,我这边循环五四呢,我就会建大概五个义部任务,我们来看这个义部任务里面具体的一个做法,他传进去一个 i, 然后呢比如说我们从一开 limit 呢,就是我们的一个五千,然后呢 cd 我们这边六了一个 candlouns, 一个 b 锁来用它来计数的,我们点进去看一下它具体的一个实现,比如说我们把配置 number 传给了它,就是当前的第一页,然后配置 side 就是五千。 然后我们来看这一段代码,这边呢主要是我们拿到了这样的一个运动码 play 啊,然后呢用了一个配置 helper, 然后去呃进行一个分页查询,比如说我第一页啊查五千条啊,在这个任务完成之后啊,我们会返回这样的一个啊 us entity 的一个 list, 那我们这边比如说五个亿不任务给他放进这个集合里面,我们这边定了一个现成池,然后去执行他这样的一个任务,把所有的任务执行完,他都会有一个 future 的一个返回,通过一个循环啊,每一个呢拿到他各自的一个结果集,然后我们加到这样的一个总的一个结果集中,并且 给它返回就可以了。然后我们看一下这样的逻辑,返回之后呢,我们就直接用一个 e z excel, 然后去给它导出。那我们来看一下我们这边定的这样的一个现成池,达到这样的一个 cpu 的一个和数 后,作为他的一个核心县城数,然后最大县城数呢就是他加一,然后呢这边还设置了等待时间,然后我们的一个呃,主色对列还有一个县城工厂,县城工厂呢,我们也是自定义的,我们可以点进去看一下,然后主要是来给他返回这样的一个新的县城,然后给他取了一个新的名字。啊,这个就不看了。 那除了 e z excel 的这样的一个导出方式呢之外呢,我们还有其他的一些导出方法,比如说来看看这样的一个, 嗯,导出方式叫 pv 的一种导出方式,它主要是这边的一个代码,主要是便利一个集合数据创建我们 excel 的内容啊,产生每一个数据行,然后产生完之后最终再导出。呃,也比较简单。呃,那今天哪个分享呢?就到这。

大部分人可能都知道,在实际的开发中用到县城的地方,我们一般不直接 newslett 去创建一个县城, 当然也不建议去用 executives 中的自带的这几个线程池,所以大部分情况下我们都会向上图这种方法去自定一个线程池去使用。那么线程池中的这些核心参数你都真正理解是什么意思了吗?接下来我们详细探讨一下。 第一个参数是 corporate size, 它的意思就是说是核心现成数,看图中我框起来的这部分文字解释其实应该已经很清楚了。 第二个参数的意思呢?就是说最大形成数,表示当前现成时最多可以有多少个现成去执行任务。第三个和第四个参数一般是合起来使用的,一个表示 具体的数值,一个表示这个数值的单位,他就表示核心县城的空闲时间大概是多久,超过这个时间就会被销毁。 walk king 表示任务队列及存放我们提交任务的一个队列。 stride factory 是县城工厂,一般的话我们使用它主要是用来创建县城的,可以对当前的县城做一些定制,比如说起一些我们自己的名字,然后做一些其他方面的一些处理。 我们可以看一下这里是我自定义的一个县城,它里边主要是实现这个牛 sir 的方法,我们去创建一个 siri 就好了。 最后一个是拒绝策略及当前现成尺满了的话,新来的任务该怎么去处理?这里我使用的是现成尺自带的拒绝策略,当然我们也可以替换成我们自己想要的 策略在里边作为根据我们实际的业务场景去定制一些拒绝策略。县城池自带的四种拒绝策略,如下图框出来的绿色主食部分,我们接下来可以详细看一下每个拒绝策略是怎么实现的。 这是第一个线程,我们可以看到他的策略是把当前的线程交给主线程去执行及执行线程时任务提交的那个线程去执行。第二个策略是直接抛出一个异常, 第三个策略是什么也不做,极意味着丢弃这个县城。第四个策略则表示移除当前任务队列对手的那个任务,然后再重新提交当前这个任务。 以上就是现成十几个核心参数的一个介绍,这里我们看一下整体的一个总结。接下来我们再用一个实际的问题来感受一下这些参数实际的意义 作用。如上图红色哐哐哐出来的这个问题。首先他会创建五个核心线程去执行前五个任务,从第六个任务开始来的,都会放到任务队列中。 当任务队列放满以后,那么当前县城池中一共就有五十五个任务,当地五十六到六十个任务来了以后,会继续创建县城去执行,因为这个时候我们只创建了五个县城吗?我们最大限程数是十,所以还可以再创建五个。 截止目前为止,县城池中已经创建了十个县城,达到最大县城数限制。然后任务队列中也已经有五十个任务了,也达到了任务队列的限制,所以当年县城池已经满了, 这个时候第七十个到一百个。这四十个任务来了以后,有些人吃已经处于满载状态,所以他们会去执行拒绝策略了,这里 有给的拒绝策略是抛出一场,所以他会抛出四十个亿场。接下来我们验证一下我们所说的结论。首先在这里我自定义一个现成池,然后具体参数如上面所施, 其中县城工厂,我这里边自定义的一个县城工厂,我们可以看一下,主要给他的就是说起了一个名字,然后还有一个计数器, 主要方便我们在打印县城的时候,可以看到这是我们自定义的县城,还有他是第几个县城,然后拒绝策略在这里我也采用的是自定义的,这里采使用那个说出一段话来模拟抛出异常吧, 这里也用了计数器,所以刚才按照我们的结论,应该会这个计数器到四十。下面这段代码是提交一百个任务,并且其中可以看到每个 任务就是模拟呃执行三十三十秒,最后一行是获取当前任务队列中的任务数。 接下来我们执行一下,可以看到县城一共是有十个没有问题,然后拒绝策略的话,一共他是有四十个,也是没有问题的, 然后队列中的任务数是五十个,所以说呢,再来看我们上面的这个结论,他是结果是按照我们的想法来执行的,你还有什么问题吗?欢迎留言。

在 supreme 的框架中,如何使用现成词来提升业务处理的速度?那首先我们这是一个使用户的程序,通过对方运行。我们先看一下这个对方运行的时候他所返回的这个十倍容器,我们通过第八个看一下,那么这个时候我们可以看到他的这个容器里边抗探索里面展开看一下, 他里边有一个并翻个头,然后这个并翻个点开之后我们可以看到里边有一个深勾丁,而不记得头。这个展开之后呢,我们发现里边呢有一个有一个对象,就是我们这个 iphone excel 的哎。那么这个呢?就是一个现成词对象,这个类叫史瑞的破踏,这个 phone 的这个类。那么这个类呢是 supreme 里边提供的类。那么这个类实际上就是对我们 jdk 里面那个现成词做了一个封装,这样一个类实际上也是一个现成词类。那么 surple 的启动之后,在 ioc 容器里边已经有这个类了,也就是他已经 配置的一个限制词对象了。那所以我们在写代码的时候,我们可以直接使用。直接使用怎么使用?这个时候我们在口诀里面我们可以直接注入 这个现成纸这类。那接下来你要出去用的时候,直接用这个现成词来操作。好,那我们来看一下这个地方是我们没有用现成词,那么他的执行就是我们这有个查询,这个查询啊,分别创新执行,然后我们看一下他花了多少时间。 那下面这个方法就是我们采用现代词啊,通过一步提交任务,这里使用这个现代词,一步提交任务,这是第一个查询,一步查询,这是第二个一步查询,也是用现代词一步查询, 然后等待他执行完成,拿到结果。最后我们看一下他那个打一段时间是多少。好,那分别访问一下。首先访问这个雷一啊,奥德一这个方法刷新,那么他是在四百九十四再刷新, 刷新哎,四百九十多。好,那这边这个我们看一下刷新,哎是两百八十多,两百八十多到两百九十多,那么他大概的提升了百分之五六十。好。这就是我们在使用部分里边可以用十倍。容器中已经提供好了一个人 县城市内啊,来去做义部任务的操作,提升我们业务处理的速度。如果这个内不满足我们的要求,我们还可以自己通过 id 注解配置这个县城内,然后来进行业务的操作。

现在我们来看怎么用这个线程词,先定一个他是个函数,给他一个类目参数,然后打印一下类,就是他们的是 lip。 三、 现成池的用法很简单,只需要把任务提交给现成池,现成池会自动安排一个现成的执行这个任务,这里我们用破掉一个三不灭的,然后把他这个传给他,后面再跟他的参数,我们就传一个大仙。这一行代码的意思就是往现成池中提交任务, 这里有一个关键词,提交任务。前面我们讲了一个任务的提交方式,分为同步和一步。同步的意思就是任务提交之后,原地等待任务的返回结果。 一步的意思就是任务提交之后,不等待继续往下执行。那我们这里通过现成次提交任务是同步还是一步呢?按理说应该是一步,对吧?因为都用到现成了,所以肯定是一步。那我们在后面再来打印一个主线程来运行看看,看到了吗?立马就打印主线程了,根本没有等到任务结束, 因为我们的任务需要睡三秒吗?如果是同步的话,应该是三秒之后才打印主线程,而这里是立马打印的主线程,所以确实是一步提交。你知道他是一步提交之后,我们在前面给他来一个否循环 fori 认就五十,然后再来提交任务,这里的参数我们就换成 i, 这个打印就不要了,现在就相当于我们往纸质里面提交了五十个任务, 但是我们的池子里现在只有十个服务员,我们来运行看下效果。我们提交到五十个任务是时刻时刻被执行的,因为池子里只有十个县城干活, 相当于房间里面有十个服务员,但门口来了五十个想要体验服务的人,那就只能时刻时刻来这十个客人体验完服务之后,服务员再去门口接十个客人来体验服务,他的效果和我们前面学的信号量很像,但本质是不一样的。对于信号量来说,他指的是锁县城,是我们自己创建的,我们创建多少县城都可以, 信号量可以控制多少线程直行其他线程主色。而对于线程词来说,线程是由线程词创建的,不是我们自己创建的,而且他控制的是线程的数量。

春招冲刺五十天系列第十三节 executives 县城工厂类有哪些常见的工厂方法? new fix thread pool, 创建一个固定大小的县城池,核心县城数与最大县城数相同,始终维持 ncs 各县城。当提交的任务数量超过县城池容量,会被放入组塞队列中等待县城空闲,适用于需要处理固定数量并发任务的情况。 new cash thread pool, 创建一个可缓存的县城池,无核心县城,最大县城数为 integer max value, 空闲县城会在六十秒后移除,能够充分利用系统资源,但可能会导致系统资源耗尽。适用于执行大量短时间异步任务的情况。 new single thread execute, 创建单县城的县城池,保证所有任务按照顺序执行。 new schedule thread pool, 创建一个定长线城池,支持定时及周期性任务的执行,适用于需要执行定时任务或周期性任务的情况。根据阿里巴巴 java 开发手册, 不建议使用 executives 工具类创建线城池,而是推荐使用 threadpool executeer, 以便根据业务更精确地控制线城池的行为和资源使用,避免潜在的性能问题和资源耗尽风险。下一节让我们讨论线城池有哪些核心参数。关注我,让你实习求职不迷路!


我们去聊一下如何利用监控对动态相程池进行调仓,为什么去聊这个问题?因为在平时使用相程池的时候, 往往对相程池的一些参数的设置是凭经验的,比如说 cpu 型相程池会把核心相程数设置为 n 加一 i o 相程池会把核心相程数设置为二 n。 但是现城池里面具体的执行情况对于我们来说是一个黑盒子,在上香之后,今天呢不知道参数是不是设置合理,所以说我们今天就想通过普罗米修斯来观察现城池里面的具体运行指标, 并且呢通过这些指标并整合 nas, 实现对现成时的一个动态的配置。我们去看一下应该如何进行整合。在这块动态现成时选用的框架是 dna 个 t b 这个框架,这个框架解决的最大痛点就是我们刚才提到那些问题,比如说参数设置、动态调仓以及现成时的一个监控, 其实它最大的一个亮点就是它使用的步骤非常方便,就可以通过下面的这五步就可以把这个动态现成时框架接进来, 在这个项目里面已经把这个框架接入进来了,哎,在这里面有个 enable 带那么个 t p, 如果说我想要去整合 noclose 配置中心,哎,就可以通过这个 noclose cloud 应用去接入,就按照它这个里面去一一的配置,就可以把 noclose 配置文件接进来实现动态调仓。 这里面呢同样的有一个监控,比如说普罗米修斯加官方的一个监控,按照他这里面的一个流程,就可以让我们的普罗米修斯去监控动态性能值的一些运行指标,那接下来我们去看一下这个效果,比如说在这块一个核心性能数值六,最大性能数值是十,哎,我们先去看下 lock 十配置文件, 在这块我设置好了,就是六和十。那我们调整一下,比如说我现在去改成八,改成八之后我们点发布,看看普罗米修斯那边能不能监控到。 ok, 我 发布啊, 我们去看一下普罗米修斯这个监控变板,你看他这块已经变了。那接下来我们去整合一个 demo, 去看一下这些指标是如何动态变换的。比如说我在这块去提供了代码,在这个代码里面会去向外去暴露一个接口,调完这个接口之后会去获取一个限能值, 并且呢可以通过这个行程池去并发的执行五十个任务,每个任务的执行时间就是三秒钟。那接下来我们去掉一下这个接口,看一下这个指标是如何去变化。 因为普罗米修斯的上传数据需要一段时间,哎,所以我们这块等一下,哎,此时动态监控已经出来了, 去正点看一下几个指标,比如说当前现成数,因为我们之前没有任务进来,所以说他的现成数就等于零,那我们一旦有任务进来之后,他会创建核心现成数,哎,所以说我们会零升为八。 那接下来还有个任务对点的剩余大小在,你看这块有一个下限,就表示我有任务进到对点里面来, 再下来有个完成任务数的统计,拒绝任务数的统计,哎,这里面的话还有个执行超时任务数,在这里面的话,其实是我们会设置一个超时时间,比如说在这块会设置一个二百毫米的超时时间,那你如果说这个任务执行超过了二百毫米,我都会认为你是执行超时的。 ok, 你 看这在下面还有一个任务的平均耗时以及任务的最大耗时,都会把一些现成时里面的执行情况给你暴露出来,并且让你整合这些指标进行调差。