
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
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)