线程池超过等待队列继续加任务会怎么样

线程池超过等待队列继续加任务会怎么样,第1张

线程池编写多线程程序时,当所有任务完成时,要做一些统计的工作。而统计工作必须要在所有任务完成才能做。所以要让主线程等待所有任务完成。可以使用ThreadPoolExecutor.awaitTermination(long timeout, TimeUnit unit)。请看示例代码:

package com.chenlb

import java.util.Random

import java.util.concurrent.LinkedBlockingQueue

import java.util.concurrent.ThreadPoolExecutor

import java.util.concurrent.TimeUnit

/**

* 线程池使用示例, 主线程等待所有任务完成再结束.

*

* @author chenlb 2008-12-2 上午10:31:03

*/

public class ThreadPoolUse {

public static class MyTask implements Runnable {

private static int id = 0

private String name = "task-"+(++id)

private int sleep

public MyTask(int sleep) {

super()

this.sleep = sleep

}

public void run() {

System.out.println(name+" -----start-----")

try {

Thread.sleep(sleep) //模拟任务执行.

} catch (InterruptedException e) {

e.printStackTrace()

}

System.out.println(name+" -----end "+sleep+"-----")

}

}

public static void main(String[] args) {

System.out.println("==================start==================")

ThreadPoolExecutor executor = new ThreadPoolExecutor(5,5, 60, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>())

int n = 10

int sleep = 10 * 1000 //10s

Random rm = new Random()

for(int i=0i<ni++) {

executor.execute(new MyTask(rm.nextInt(sleep)+1))

}

executor.shutdown()//只是不能再提交新任务,等待执行的任务不受影响

try {

boolean loop = true

do {//等待所有任务完成

loop = !executor.awaitTermination(2, TimeUnit.SECONDS) //阻塞,直到线程池里所有任务结束

} while(loop)

} catch (InterruptedException e) {

e.printStackTrace()

}

System.out.println("==================end====================")

}

}

当然还有其它方法。

http://xtu-xiaoxin.iteye.com/blog/649677

shutDown()

当线程池调用该方法时,线程池的状态则立刻变成SHUTDOWN状态。此时,则不能再往线程池中添加任何任务,否则将会抛出RejectedExecutionException异常。但是,此时线程池不会立刻退出,直到添加到线程池中的任务都已经处理完成,才会退出。 唯一的影响就是不能再提交任务了,正则执行的任务即使在阻塞着也不会结束,在排队的任务也不会取消。

shutdownNow()

根据JDK文档描述,大致意思是:执行该方法,线程池的状态立刻变成STOP状态,并试图停止所有正在执行的线程,不再处理还在池队列中等待的任务,当然,它会返回那些未执行的任务。

它试图终止线程的方法是通过调用Thread.interrupt()方法来实现的,但是大家知道,这种方法的作用有限,如果线程中没有sleep 、wait、Condition、定时锁等应用, interrupt()方法是无法中断当前的线程的。所以,ShutdownNow()并不代表线程池就一定立即就能退出,它可能必须要等待所有正在执行的任务都执行完成了才能退出。

上面对shutDown()以及shutDownNow()作了一个简单的、理论上的分析。如果想知道why,则需要亲自打开JDK源码,分析分析。

想要分析shutDown()以及shutDownNow()源码,我建议首先要对ThreadPoolExecutor有个大概了解。因为关闭线程池的所有方法逻辑都在ThreadPoolExecutor中处理的。

在IOS / TVOS中有队列/线程,每个线程都有自己的类型或优先级,也称为“服务质量”或简称为“QOS”,这意味着cpu应该处理此线程的紧迫程度,可能性是:

QOS_CLASS_DEFAULT

QOS_CLASS_USER_INITIATED

QOS_CLASS_UTILITY

QOS_CLASS_BACKGROUND

QOS_CLASS_UNSPECIFIED

QOS_CLASS_USER_INTERACTIVE

一旦在同一个队列中同时运行太多任务,那么 *** 作系统会通知您,它不能同时在同一优先级中执行所有这些任务(每个队列的堆栈大小都有限制) ,它表示“OverCommit”,这意味着您已经提交了队列(在您的情况下为“Default-QOS”队列),并且它退出,因为此时无法接收到更多任务,并以您想要的方式执行它们。

解:

您应该做的是首先找到导致此崩溃的“dispatch_async”命令,然后使用其他队列之一(这意味着预期响应速度较慢,然后预期该任务),

通常开发者不要考虑它,只需使用这样的默认优先级/队列的主队列:

dispatch_async(dispatch_get_main_queue()) {

// some task to perform

print("This is my task")

}

为了解决这个问题(如果应用程序通知你已经超过主队列)是将其更改为其他队列之一,如下所示:

let qualityOfServiceClass = QOS_CLASS_BACKGROUND

let backgroundQueue = dispatch_get_global_queue(qualityOfServiceClass, 0)

dispatch_async(backgroundQueue, {

// some task to perform

print("This is my task")

})

如果不需要执行后台(或并行),甚至可以忽略dispatch_async命令,只需执行如下命令:

// some task to perform

print("This is my task")

原文链接 : https://stackoverflow.com/questions/27948618/consistent-dispatch-queue-com-apple-root-default-qos-overcommit-crash


欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/yw/12044573.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-05-20
下一篇2023-05-20

发表评论

登录后才能评论

评论列表(0条)

    保存