97色伦色在线综合视频,无玛专区,18videosex性欧美黑色,日韩黄色电影免费在线观看,国产精品伦理一区二区三区,在线视频欧美日韩,亚洲欧美在线中文字幕不卡

大連仟億科技網(wǎng)站建設(shè)公司怎么樣如何將網(wǎng)站做成app

鶴壁市浩天電氣有限公司 2026/01/24 14:07:02
大連仟億科技網(wǎng)站建設(shè)公司怎么樣,如何將網(wǎng)站做成app,重慶市工程建設(shè)招標(biāo)投標(biāo)信息網(wǎng),官方網(wǎng)站建設(shè)屬于什么科目在 Java 并發(fā)編程領(lǐng)域#xff0c;線程池是提升程序性能、優(yōu)化資源利用率的核心組件#xff0c;而ThreadPoolExecutor作為 JDK 原生線程池的實(shí)現(xiàn)類#xff0c;更是開發(fā)者必須掌握的關(guān)鍵技術(shù)點(diǎn)。本文將從ThreadPoolExecutor的核心原理出發(fā)#xff0c;深入解析其構(gòu)造參數(shù)、工作…在 Java 并發(fā)編程領(lǐng)域線程池是提升程序性能、優(yōu)化資源利用率的核心組件而ThreadPoolExecutor作為 JDK 原生線程池的實(shí)現(xiàn)類更是開發(fā)者必須掌握的關(guān)鍵技術(shù)點(diǎn)。本文將從ThreadPoolExecutor的核心原理出發(fā)深入解析其構(gòu)造參數(shù)、工作流程、狀態(tài)管理機(jī)制并結(jié)合實(shí)戰(zhàn)場(chǎng)景講解其使用技巧與常見問題解決方案幫助讀者真正做到知其然且知其所以然。一、為什么需要 ThreadPoolExecutor—— 線程池的核心價(jià)值在傳統(tǒng)的并發(fā)編程中開發(fā)者通常會(huì)通過new Thread()的方式直接創(chuàng)建線程但這種方式存在明顯的缺陷資源消耗過大每次創(chuàng)建線程都會(huì)消耗內(nèi)存默認(rèn)棧大小 1MB和 CPU 資源頻繁創(chuàng)建銷毀線程會(huì)引發(fā)大量上下文切換嚴(yán)重影響程序性能穩(wěn)定性風(fēng)險(xiǎn)若業(yè)務(wù)高峰期瞬間創(chuàng)建大量線程可能導(dǎo)致 JVM 內(nèi)存溢出OOM或系統(tǒng)資源耗盡可管理性差分散的線程無法統(tǒng)一監(jiān)控、調(diào)度和控制難以實(shí)現(xiàn)任務(wù)優(yōu)先級(jí)、超時(shí)控制等高級(jí)功能。ThreadPoolExecutor通過線程復(fù)用、任務(wù)隊(duì)列緩沖、線程生命周期管理三大核心機(jī)制完美解決了上述問題。其本質(zhì)是一個(gè) 線程池 任務(wù)隊(duì)列 的組合模型通過預(yù)先創(chuàng)建一定數(shù)量的核心線程將任務(wù)提交到隊(duì)列中逐步執(zhí)行避免了線程頻繁創(chuàng)建銷毀的開銷同時(shí)提供了豐富的配置參數(shù)和擴(kuò)展接口滿足不同場(chǎng)景下的并發(fā)需求。二、ThreadPoolExecutor 核心原理剖析2.1 核心構(gòu)造參數(shù)解析ThreadPoolExecutor的核心構(gòu)造方法包含 7 個(gè)參數(shù)每個(gè)參數(shù)都直接影響線程池的行為理解這些參數(shù)是正確使用線程池的前提public ThreadPoolExecutor(int corePoolSize, // 核心線程數(shù)int maximumPoolSize, // 最大線程數(shù)long keepAliveTime, // 非核心線程空閑存活時(shí)間TimeUnit unit, // 存活時(shí)間單位BlockingQueueQueue, // 任務(wù)阻塞隊(duì)列ThreadFactory threadFactory, // 線程工廠RejectedExecutionHandler handler // 拒絕策略) {// 構(gòu)造邏輯}1. 核心線程數(shù)corePoolSize線程池長(zhǎng)期維持的線程數(shù)量即使線程處于空閑狀態(tài)也不會(huì)銷毀除非設(shè)置allowCoreThreadTimeOuttrue當(dāng)任務(wù)數(shù)小于核心線程數(shù)時(shí)線程池會(huì)直接創(chuàng)建新線程執(zhí)行任務(wù)示例若corePoolSize5當(dāng)前有 3 個(gè)任務(wù)則會(huì)創(chuàng)建 3 個(gè)線程剩余 2 個(gè)核心線程位置處于空閑狀態(tài)。2. 最大線程數(shù)maximumPoolSize線程池允許創(chuàng)建的最大線程數(shù)量是核心線程數(shù)與非核心線程數(shù)的總和當(dāng)任務(wù)隊(duì)列滿且核心線程全部忙碌時(shí)線程池會(huì)創(chuàng)建非核心線程執(zhí)行任務(wù)直到線程總數(shù)達(dá)到maximumPoolSize注意若使用無界隊(duì)列如LinkedBlockingQueuemaximumPoolSize參數(shù)會(huì)失效因?yàn)槿蝿?wù)隊(duì)列永遠(yuǎn)不會(huì)滿無法觸發(fā)非核心線程的創(chuàng)建。3. 空閑存活時(shí)間keepAliveTime unit僅對(duì)非核心線程生效當(dāng)非核心線程空閑時(shí)間超過keepAliveTime時(shí)會(huì)被線程池銷毀釋放資源通過threadPool.setAllowCoreThreadTimeOut(true)可讓核心線程也遵循此規(guī)則適用于任務(wù)量波動(dòng)較大的場(chǎng)景常見單位TimeUnit.SECONDS秒、TimeUnit.MILLISECONDS毫秒。4. 任務(wù)阻塞隊(duì)列workQueue用于存儲(chǔ)等待執(zhí)行的任務(wù)是線程池的 緩沖池常見實(shí)現(xiàn)類及特性如下隊(duì)列類型特點(diǎn)適用場(chǎng)景ArrayBlockingQueue有界隊(duì)列基于數(shù)組實(shí)現(xiàn)需指定容量對(duì)任務(wù)量有明確控制的場(chǎng)景LinkedBlockingQueue默認(rèn)無界容量 Integer.MAX_VALUE基于鏈表實(shí)現(xiàn)任務(wù)量穩(wěn)定無內(nèi)存溢出風(fēng)險(xiǎn)的場(chǎng)景SynchronousQueue無容量隊(duì)列任務(wù)需立即被線程執(zhí)行高并發(fā)、低延遲場(chǎng)景如 NettyPriorityBlockingQueue優(yōu)先級(jí)隊(duì)列按任務(wù)優(yōu)先級(jí)排序任務(wù)有明確優(yōu)先級(jí)的場(chǎng)景5. 線程工廠threadFactory用于創(chuàng)建線程的工廠類可自定義線程的名稱、優(yōu)先級(jí)、是否為守護(hù)線程等屬性自定義線程工廠示例ThreadFactory customFactory new ThreadFactory() {private final AtomicInteger threadNum new AtomicInteger(1);Overridepublic Thread newThread(Runnable r) {Thread thread new Thread(r);thread.setName(biz-thread- threadNum.getAndIncrement()); // 自定義線程名thread.setDaemon(false); // 非守護(hù)線程thread.setPriority(Thread.NORM_PRIORITY); // 正常優(yōu)先級(jí)return thread;}};自定義線程名有助于日志排查例如通過線程名快速定位業(yè)務(wù)模塊。6. 拒絕策略RejectedExecutionHandler當(dāng)線程池達(dá)到最大線程數(shù)且任務(wù)隊(duì)列滿時(shí)對(duì)新提交的任務(wù)采取的處理策略JDK 默認(rèn)提供 4 種實(shí)現(xiàn)拒絕策略處理邏輯適用場(chǎng)景AbortPolicy直接拋出 RejectedExecutionException不允許任務(wù)丟失的場(chǎng)景需手動(dòng)處理異常CallerRunsPolicy由提交任務(wù)的線程調(diào)用者自己執(zhí)行并發(fā)量較小允許主線程執(zhí)行任務(wù)的場(chǎng)景DiscardPolicy直接丟棄任務(wù)不拋出異常任務(wù)可丟失的場(chǎng)景如日志收集DiscardOldestPolicy丟棄隊(duì)列中最舊的任務(wù)執(zhí)行新任務(wù)任務(wù)時(shí)效性要求高的場(chǎng)景也可通過實(shí)現(xiàn)RejectedExecutionHandler接口自定義拒絕策略例如將任務(wù)寫入持久化存儲(chǔ)如 Redis、數(shù)據(jù)庫待線程池空閑后重試。2.2 線程池工作流程ThreadPoolExecutor的任務(wù)執(zhí)行流程是其核心邏輯可總結(jié)為以下 5 個(gè)步驟判斷核心線程是否空閑若核心線程數(shù)未達(dá)到corePoolSize則創(chuàng)建核心線程執(zhí)行任務(wù)若核心線程已全部忙碌進(jìn)入下一步判斷任務(wù)隊(duì)列是否已滿若任務(wù)隊(duì)列未滿將任務(wù)放入隊(duì)列等待執(zhí)行若隊(duì)列已滿進(jìn)入下一步判斷是否達(dá)到最大線程數(shù)若當(dāng)前線程數(shù)未達(dá)到maximumPoolSize創(chuàng)建非核心線程執(zhí)行任務(wù)若已達(dá)到最大值進(jìn)入下一步執(zhí)行拒絕策略根據(jù)配置的RejectedExecutionHandler處理新提交的任務(wù)線程復(fù)用與銷毀任務(wù)執(zhí)行完成后線程不會(huì)立即銷毀而是回到線程池等待新任務(wù)核心線程長(zhǎng)期存活非核心線程空閑超時(shí)后銷毀。為更直觀理解下圖展示了線程池的工作流程文字描述替代圖示任務(wù)提交 → 核心線程未滿→ 創(chuàng)核心線程執(zhí)行 → 結(jié)束↓ 否隊(duì)列未滿→ 任務(wù)入隊(duì) → 結(jié)束↓ 否最大線程未滿→ 創(chuàng)非核心線程執(zhí)行 → 結(jié)束↓ 否執(zhí)行拒絕策略 → 結(jié)束2.3 線程池狀態(tài)管理ThreadPoolExecutor通過一個(gè)原子變量ctl包含線程池狀態(tài)和線程數(shù)量管理生命周期線程池包含 5 種狀態(tài)狀態(tài)名稱狀態(tài)值描述RUNNING-1正常運(yùn)行狀態(tài)可接收任務(wù)并執(zhí)行SHUTDOWN0調(diào)用 shutdown () 后進(jìn)入不接收新任務(wù)執(zhí)行完隊(duì)列中任務(wù)STOP1調(diào)用 shutdownNow () 后進(jìn)入不接收新任務(wù)中斷正在執(zhí)行的任務(wù)清空隊(duì)列TIDYING2所有任務(wù)執(zhí)行完成線程數(shù)為 0準(zhǔn)備進(jìn)入 TERMINATED 狀態(tài)TERMINATED3線程池完全終止所有資源釋放狀態(tài)轉(zhuǎn)換路徑RUNNING → SHUTDOWN調(diào)用shutdown()RUNNING → STOP調(diào)用shutdownNow()SHUTDOWN → TIDYING隊(duì)列空且所有線程執(zhí)行完成STOP → TIDYING所有線程執(zhí)行完成TIDYING → TERMINATED調(diào)用terminated()方法可重寫擴(kuò)展。三、ThreadPoolExecutor 實(shí)戰(zhàn)應(yīng)用3.1 線程池創(chuàng)建規(guī)范避免使用 Executors 工具類JDK 提供的Executors工具類如Executors.newFixedThreadPool()、Executors.newCachedThreadPool()雖然簡(jiǎn)化了線程池創(chuàng)建但存在嚴(yán)重的資源風(fēng)險(xiǎn)newFixedThreadPool()使用無界LinkedBlockingQueue任務(wù)過多時(shí)會(huì)導(dǎo)致 OOMnewCachedThreadPool()maximumPoolSizeInteger.MAX_VALUE可能創(chuàng)建大量線程導(dǎo)致 OOMnewScheduledThreadPool()同樣使用無界隊(duì)列存在 OOM 風(fēng)險(xiǎn)。規(guī)范做法直接通過ThreadPoolExecutor構(gòu)造方法創(chuàng)建線程池明確指定核心參數(shù)尤其是隊(duì)列容量和最大線程數(shù)避免無界資源耗盡問題。3.2 實(shí)戰(zhàn)場(chǎng)景電商訂單處理線程池以電商平臺(tái)的訂單處理場(chǎng)景為例需求如下高峰期每秒新增 1000 個(gè)訂單每個(gè)訂單處理耗時(shí)約 100ms允許訂單有 1 秒的延遲不允許訂單丟失服務(wù)器 CPU 核心數(shù)為 8 核。1. 參數(shù)計(jì)算核心線程數(shù)corePoolSizeCPU 密集型任務(wù)建議設(shè)為CPU核心數(shù)1IO 密集型任務(wù)建議設(shè)為CPU核心數(shù)*2。訂單處理涉及 DB 操作IO 密集故corePoolSize8*216最大線程數(shù)maximumPoolSize考慮高峰期冗余設(shè)為corePoolSize*232空閑存活時(shí)間非核心線程空閑 10 秒后銷毀keepAliveTime10unitTimeUnit.SECONDS任務(wù)隊(duì)列允許 1 秒延遲每秒 1000 個(gè)任務(wù)隊(duì)列容量設(shè)為1000*11000ArrayBlockingQueue拒絕策略訂單不允許丟失使用自定義拒絕策略寫入 Redis 重試。2. 代碼實(shí)現(xiàn)public class OrderThreadPool {// 線程池單例使用枚舉確保線程安全private enum Singleton {INSTANCE;private final ThreadPoolExecutor threadPool;Singleton() {// 1. 自定義線程工廠ThreadFactory threadFactory new ThreadFactory() {private final AtomicInteger count new AtomicInteger(1);Overridepublic Thread newThread(Runnable r) {Thread thread new Thread(r);thread.setName(order-thread- count.getAndIncrement());thread.setPriority(Thread.NORM_PRIORITY);return thread;}};// 2. 自定義拒絕策略任務(wù)寫入Redis后續(xù)重試RejectedExecutionHandler rejectedHandler (r, executor) - {if (r instanceof OrderTask) {OrderTask task (OrderTask) r;RedisUtil.set(order_retry: task.getOrderId(), task, 3600); // 1小時(shí)過期log.warn(訂單處理線程池繁忙訂單{}已加入重試隊(duì)列, task.getOrderId());}};// 3. 創(chuàng)建線程池threadPool new ThreadPoolExecutor(16, // corePoolSize32, // maximumPoolSize10, // keepAliveTimeTimeUnit.SECONDS, // unitnew ArrayBlockingQueue0), // workQueuethreadFactory, // threadFactoryrejectedHandler // rejectedHandler);// 允許核心線程超時(shí)銷毀非必需根據(jù)場(chǎng)景調(diào)整threadPool.allowCoreThreadTimeOut(false);}public ThreadPoolExecutor getInstance() {return threadPool;}}// 獲取線程池實(shí)例public static ThreadPoolExecutor getInstance() {return Singleton.INSTANCE.getInstance();}// 提交訂單任務(wù)public static void submitOrderTask(OrderTask task) {getInstance().submit(task);}// 關(guān)閉線程池建議在應(yīng)用關(guān)閉時(shí)調(diào)用public static void shutdown() {ThreadPoolExecutor executor getInstance();if (!executor.isShutdown()) {executor.shutdown();// 等待線程池關(guān)閉最多等待30秒try {if (!executor.awaitTermination(30, TimeUnit.SECONDS)) {executor.shutdownNow(); // 強(qiáng)制關(guān)閉}} catch (InterruptedException e) {executor.shutdownNow();Thread.currentThread().interrupt();}}}}// 訂單任務(wù)類class OrderTask implements Runnable {private String orderId;private OrderService orderService;public OrderTask(String orderId, OrderService orderService) {this.orderId orderId;this.orderService orderService;}public String getOrderId() {return orderId;}Overridepublic void run() {try {// 處理訂單邏輯如創(chuàng)建訂單、扣減庫存、發(fā)送通知orderService.processOrder(orderId);} catch (Exception e) {log.error(訂單{}處理失敗, orderId, e);// 異常處理如重試、告警}}}3.3 線程池監(jiān)控與調(diào)優(yōu)為確保線程池穩(wěn)定運(yùn)行需對(duì)其進(jìn)行監(jiān)控常用監(jiān)控指標(biāo)及實(shí)現(xiàn)方式如下1. 核心監(jiān)控指標(biāo)活躍線程數(shù)threadPool.getActiveCount()任務(wù)總數(shù)threadPool.getTaskCount()已完成任務(wù)數(shù)threadPool.getCompletedTaskCount()隊(duì)列剩余容量workQueue.remainingCapacity()線程池狀態(tài)threadPool.isShutdown()、threadPool.isTerminated()。2. 監(jiān)控實(shí)現(xiàn)結(jié)合 SpringBootComponentpublic class ThreadPoolMonitor implements CommandLineRunner {Overridepublic void run(String... args) throws Exception {// 定時(shí)監(jiān)控線程池狀態(tài)每5秒輸出一次ScheduledExecutorService monitorExecutor Executors.newSingleThreadScheduledExecutor();monitorExecutor.scheduleAtFixedRate(() - {ThreadPoolExecutor orderPool OrderThreadPool.getInstance();log.info( 訂單線程池監(jiān)控 );log.info(核心線程數(shù){}, orderPool.getCorePoolSize());log.info(活躍線程數(shù){}, orderPool.getActiveCount());log.info(最大線程數(shù){}, orderPool.getMaximumPoolSize());log.info(已完成任務(wù)數(shù){}, orderPool.getCompletedTaskCount());log.info(隊(duì)列剩余容量{}, orderPool.getQueue().remainingCapacity());log.info(線程池狀態(tài){}, orderPool.isShutdown() ? 已關(guān)閉 : 運(yùn)行中);}, 0, 5, TimeUnit.SECONDS);}}3. 調(diào)優(yōu)建議核心線程數(shù)IO 密集型任務(wù)可適當(dāng)增大如CPU*2CPU 密集型任務(wù)建議與 CPU 核心數(shù)持平或 1隊(duì)列容量避免過大導(dǎo)致任務(wù)延遲過高或過小頻繁觸發(fā)拒絕策略根據(jù)業(yè)務(wù)延遲要求計(jì)算拒絕策略核心業(yè)務(wù)優(yōu)先使用自定義策略如持久化重試非核心業(yè)務(wù)可使用DiscardPolicy監(jiān)控告警當(dāng)活躍線程數(shù)長(zhǎng)期接近最大線程數(shù)或隊(duì)列剩余容量為 0 時(shí)觸發(fā)告警如短信、釘釘通知及時(shí)擴(kuò)容或優(yōu)化任務(wù)。四、常見問題與解決方案4.1 線程池任務(wù)執(zhí)行異常丟失問題現(xiàn)象通過execute()提交任務(wù)時(shí)若任務(wù)執(zhí)行拋出異常線程池會(huì)直接銷毀該線程但異常信息不會(huì)主動(dòng)打印導(dǎo)致問題排查困難。解決方案在Runnable的run()方法中捕獲所有異常并打印日志使用submit()提交任務(wù)通過Future.get()獲取異常信息Future? future OrderThreadPool.getInstance().submit(task);try {future.get(); // 阻塞獲取任務(wù)執(zhí)行結(jié)果若有異常會(huì)拋出} catch (InterruptedException | ExecutionException e) {log.error(任務(wù)執(zhí)行異常, e);}4.2 線程池關(guān)閉后任務(wù)丟失問題現(xiàn)象調(diào)用shutdown()后線程池會(huì)執(zhí)行完隊(duì)列中的任務(wù)但若調(diào)用shutdownNow()會(huì)中斷正在執(zhí)行的任務(wù)并清空隊(duì)列導(dǎo)致任務(wù)丟失。解決方案優(yōu)先使用shutdown()關(guān)閉線程池避免shutdownNow()若必須使用shutdownNow()需在任務(wù)中處理中斷信號(hào)確保數(shù)據(jù)一致性O(shè)verridepublic void run() {try {while (!Thread.currentThread().isInterrupted()) {// 任務(wù)執(zhí)行邏輯分步驟執(zhí)行每步檢查中斷狀態(tài)if (step1Done) break;step1();if (step2Done) break;step2();}} catch (InterruptedException e) {log.warn(任務(wù)被中斷已執(zhí)行步驟{}, step1Done ? step1完成 : 未完成);// 數(shù)據(jù)回滾或保存中間狀態(tài)Thread.currentThread().interrupt(); // 恢復(fù)中斷狀態(tài)}}4.3 線程池參數(shù)配置不合理導(dǎo)致性能瓶頸問題現(xiàn)象任務(wù)執(zhí)行延遲過高或頻繁觸發(fā)拒絕策略但服務(wù)器 CPU、內(nèi)存使用率未達(dá)上限。排查與解決步驟通過監(jiān)控查看活躍線程數(shù)、隊(duì)列容量、已完成任務(wù)數(shù)判斷瓶頸點(diǎn)若活躍線程數(shù)長(zhǎng)期低于核心線程數(shù)可能是任務(wù)提交頻率低無需調(diào)優(yōu)若隊(duì)列滿且活躍線程數(shù)達(dá)到最大線程數(shù)檢查任務(wù)執(zhí)行耗時(shí)是否過長(zhǎng)如 DB 查詢慢優(yōu)化業(yè)務(wù)邏輯適當(dāng)增大最大線程數(shù)或隊(duì)列容量需評(píng)估服務(wù)器資源若 CPU 使用率過高可能是核心線程數(shù)過多導(dǎo)致上下文切換頻繁需減少核心線程數(shù)。五、總結(jié)ThreadPoolExecutor作為 Java 并發(fā)編程的核心組件其設(shè)計(jì)思想池化技術(shù)、生產(chǎn)者 - 消費(fèi)者模型和實(shí)現(xiàn)細(xì)節(jié)值得深入研究。本文從原理、實(shí)戰(zhàn)、問題解決三個(gè)維度詳細(xì)講解了ThreadPoolExecutor的核心參數(shù)、工作流程、創(chuàng)建規(guī)范、監(jiān)控調(diào)優(yōu)及常見問題希望能幫助開發(fā)者真正掌握線程池的使用技巧。在實(shí)際開發(fā)中線程池的配置沒有 銀彈需要結(jié)合業(yè)務(wù)場(chǎng)景如任務(wù)類型、延遲要求、數(shù)據(jù)安全性和服務(wù)器資源CPU、內(nèi)存進(jìn)行靈活調(diào)整同時(shí)通過完善的監(jiān)控和告警機(jī)制確保線程池穩(wěn)定運(yùn)行。只有將技術(shù)原理與業(yè)務(wù)實(shí)踐相結(jié)合才能充分發(fā)揮ThreadPoolExecutor的價(jià)值構(gòu)建高性能、高可用的并發(fā)系統(tǒng)。
版權(quán)聲明: 本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)聯(lián)系我們進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

常州網(wǎng)站建設(shè)要多少錢深圳創(chuàng)意網(wǎng)站

常州網(wǎng)站建設(shè)要多少錢,深圳創(chuàng)意網(wǎng)站,網(wǎng)站首頁標(biāo)題怎么寫,活動(dòng)推廣方案策劃第一章#xff1a;Java智能運(yùn)維中日志分析的核心價(jià)值在現(xiàn)代分布式系統(tǒng)中#xff0c;Java應(yīng)用產(chǎn)生的海量日志數(shù)據(jù)成為運(yùn)維決

2026/01/23 15:54:01

跨境電商網(wǎng)站 建設(shè)要求中國徐州網(wǎng)官網(wǎng)

跨境電商網(wǎng)站 建設(shè)要求,中國徐州網(wǎng)官網(wǎng),專做奢侈品的網(wǎng)站,國內(nèi)有獎(jiǎng)活動(dòng)第一分享平臺(tái)海風(fēng)攜著南海的濕潤氣息漫過坡地#xff0c;陽光透過疏密相間的枝葉在石階上投下斑駁光影#xff0c;這便是銅鼓嶺給人的

2026/01/23 10:40:01