文章摘自:不才陈某 码猿技术专栏
在后台开发中,会经常用到线程池技术,对于线程池核心参数的配置很大程度上依靠经验。然而,由于系统运行过程中存在的不确定性,我们很难一劳永逸地规划一个合理的线程池参数。在对线程池配置参数进行调整时,一般需要对服务进行重启,这样修改的成本就会偏高。一种解决办法就是,将线程池的配置放到平台侧,运行开发同学根据系统运行情况对核心参数进行动态配置。
本文以Nacos作为服务配置中心,以修改线程池核心线程数、最大线程数为例,实现一个简单的动态化线程池。
文章摘自:不才陈某 码猿技术专栏
在后台开发中,会经常用到线程池技术,对于线程池核心参数的配置很大程度上依靠经验。然而,由于系统运行过程中存在的不确定性,我们很难一劳永逸地规划一个合理的线程池参数。在对线程池配置参数进行调整时,一般需要对服务进行重启,这样修改的成本就会偏高。一种解决办法就是,将线程池的配置放到平台侧,运行开发同学根据系统运行情况对核心参数进行动态配置。
本文以Nacos作为服务配置中心,以修改线程池核心线程数、最大线程数为例,实现一个简单的动态化线程池。
是一个任务定时周期的延迟执行的队列。根据指定的执行时间从小到大排序,否则根据插入到队列的先后排序。newScheduledThreadPool 线程池使用了这个队列。
DelayQueue提供了在指定时间才能获取队列元素的功能,队列头元素是最接近过期的元素。
没有过期元素的话,使用poll()方法会返回null值,超时判定是通过getDelay(TimeUnit.NANOSECONDS)方法的返回值小于等于0来判断。 延时队列不能存放空元素。
一般使用take()方法阻塞等待,有过期元素时继续。
创建一个线程对象后,该线程对象就处于新建状态,此时它不能运行,与其他Java对象一样,仅仅由Java虚拟机为其分配了内存,没有表现出任何线程的动态特征。
听到线程池、线程,不禁都为为之端正姿势
用户级线程(ULT):用户程序实现,不依赖操作系统核心,应用提供创建、同步、调度和管理新城的函数来控制用户线程。不需要用户态/内核态之间的切换,速度快,内核对ULT无感知。 内核线程(KLT):系统内核管理线程,内核保存线程的状态和上下文,线程阻塞不会引起进程阻塞,在多处理器系统上,多线程在处理器上并行运行,线程创建、调度和管理由内核完成,效率要比ULT慢,比进程操作快。 直观感受下内核线程:如果创建的是内核线程,那么这个数字会增多。
volatile就可以说是java虚拟机提供的最轻量级的同步机制。但它同时不容易被正确理解,也至于在并发编程中很多程序员遇到线程安全的问题就会使用synchronized。Java内存模型告诉我们,各个线程会将共享变量从主内存中拷贝到工作内存,然后执行引擎会基于工作内存中的数据进行操作处理。线程在工作内存进行操作后何时会写到主内存中?这个时机对普通变量是没有规定的,而针对volatile修饰的变量给java虚拟机特殊的约定,线程对volatile变量的修改会立刻被其他线程所感知,即不会出现数据脏读的现象,从而保证数据的“可见性”。
现在我们有了一个大概的印象就是:被volatile修饰的变量能够保证每个线程能够获取该变量的最新值,从而避免出现数据脏读的现象。
异常的种类