1,线程池ThreadPoolExecutor
1.1,如果某个线程的空闲时间超过了存或时间,那么将被标记为可回收的,并且当线程池的当前大小超过了基本大小时,这个线程将被终止
1.2,通过调节线程池的基本大小和存或时间,可以帮助线程池回收空闲线程占有的资源。
1.3,newFixedThreadPool工厂方法将线程池基本大小和最大大小设置为参数中的指定值,而且创建的线程池超时(默认使用*队列LinkedBlockingQueue)
1.4,newCacheThreadPool工厂方法将线程池基本大小设置为0,最大大小设置为Integer.MAX_VALUE,超时设置为1分钟(默认使用同步移交机制SynchronousQueue)
1.5,newSingleThreadPool工厂方法是个特例,它能确保不会有任务并发执行,因为它通过现场封闭来实现线程的安全性。(默认使用*队列LinkedBlockingQueue)
1.6,ThreadPoolExecutor允许提供一个BlockingQueue来保存等待执行的任务。基本的任务排队方法有3中:*队列,有界队列和同步移交(Synchronous Handoff)
1.7,比较稳妥的资源管理策略是使用有界队列,避免资源耗尽的情况发生。但同时带来一个问题:当队列填满后,新的任务该怎么处理?
1.8,只有当任务相互独立时,为线程池或工作队列设置界限才是合理的。如果任务之间存在依赖性,那么有界的线程池或者队列可能导致线程的饥饿死锁问题,此时应该使用*的线程池。
2,饱和策略
2.1,ThreadPoolExecutor的饱和策略可以通过调用setRejectedExecutionHandle来修改。
2.2,JDK提供了几种不同的RejectExecutionHandle实现:AbortPolucy,CallerRunsPolicy,DiscardPolicy和DiscardOldestPolicy。
2.3,默认的饱和策略是AbortPolicy,如果新任务无法提交到队列中等待执行,将被抛弃并抛出RejectExecutionException
2.4,DiscardOldestPolicy会抛弃下一个将被执行的任务,如果等待队列时优先级队列,将抛弃优先级最高的任务。所有要慎用DiscardOldestPolicy和优先级队列放一起用
2.5,CallerRunsPolicy既不会抛弃任务,也不会抛出异常,而是将任务会退给调用者执行。例如在webserver中采用此策略,当工作线程池满了后,下一个任务会由调用execute的主线程执行,这样主线程就没法再向线程池提交任务,再此期间主线程不会调用accept,因此请求被保存在TCP层的队列中而不是应用程序队列中。如果持续过载那么这种过载情况会逐渐向外蔓延开来。从线程池到工作队列到应用程序再到TCP层,最总到达客户端,导致服务器在高负载下实现一种平缓的性能降低。
3,线程工厂
3.1,每当线程池需要创建线程时,都是通过线程工厂方法来完成,可以通过制定一个线程工厂的方法,来定制线程池的配置信息,如:给线程线程指定UncaughtExceptionHandle,给线程指定名字,打印特定线程日志或调试信息
3.2,如果应用程序中需要利用安全策略来控制对某些特殊代码库的访问权限,可以通过Executors中的privilegeThreadFactory工厂来定制自己的线程工厂。如果不适用privilegeThreadFactory,线程池创建的线程将从调用execute或submit的客户端程序继承访问权限
3.3,Executors中包含一个unconfigurableExecutorService工厂方法,该方法对一个现有的ExecutorService进行包装,使其只暴露ExecutorService的方法,因此不能对其进行参数配置了
4,ThreadPoolExecutor时可扩展的,它提供了几个可以在子类中改写的方法:beforeExecute,afterExecute和terminated
相关文章
- java并发编程(十五)----(线程池)java线程池简介
- Java高并发实战:利用线程池和Redis实现高效数据入库
- Java并发编程(二)线程任务的中断(interrupt)
- python 并发编程之多线程的缺点 (对比JAVA多线程)
- Java多线程并发04——合理使用线程池
- 【Java并发编程】之六:Runnable和Thread实现多线程的区别(含代码)
- Java并发编程——创建线程的三种方法以及区别
- java并发编程(十七)Executor框架和线程池
- RabbitMQ 优点和缺点- 消息可靠性:RabbitMQ 提供了持久化功能和消息确认机制,确保消息在各种情况下都能可靠地存储和处理。 灵活的路由:通过多种交换机类型和绑定规则,RabbitMQ 能够灵活地路由消息到指定的队列。 支持多种消息协议:实现了 AMQP 等(MQTT、STOMP)标准化、开放的消息队列协议,使其能够与多种语言编写的应用程序进行通信。 插件化扩展:RabbitMQ 提供了丰富的插件系统,可以通过插件扩展功能,如死信队列、压缩、追踪等。 高可用性:支持集群模式和镜像队列,确保服务的可用性 易用性和可管理性:提供了丰富的 API 和管理工具,以及多种客户端库和框架支持,易于集成和使用。 多语言支持:RabbitMQ 支持多种编程语言的客户端,包括 Java、Python、Ruby、C#、Node.js 等,方便开发人员集成到各种应用中。 高性能:在处理大量并发消息时表现出色。 广泛的社区支持:拥有庞大的开发者社区和丰富的文档资源。 劣势: 性能和吞吐量较低:相比于 Apache Kafka 等面向大数据流处理的消息队列系统,RabbitMQ 的吞吐量较低,不适合处理海量的实时数据流。RabbitMQ 的设计更注重消息的可靠性和灵活性,而非极高的吞吐性能。
- java 多线程:线程池的使用Executors~ExecutorService; newCachedThreadPool;newFixedThreadPool(int threadNum);ScheduledExecutorService