线程池 基本原理

做个Java开发的小伙伴,或多或少的接触过线程池,但是为什么Java要提供线程池这个工具类呢?相信大家都听说过,线程对象比较重,重是什么意思?大家应该也接触过其他池化技术,比如数据库连接池,那这些池化技术和线程池的原理是否一样呢?我们先来明确一下,重到底是什么意思?一个普通的Java对象,它的创建过程无非就是加载类,在堆内存中分配空间,进行初始化,经过这三步Java对象就创建完成了,而线程对象的创建,除了需要经过这三步,还需要操作系统的配合,真正线程的创建是交给操作系统的,而操作系统创建线程就会用到其他资源(如果学过操作系统,至少应该知道操作系统会维护一个TCB),正是由于操作系统申请了其他资源,所以导致线程对象比普通的Java对象重。而对于这些比较重的对象,但是我们又需要频繁使用,一般我们会选择将它们缓存起来,用的时候申请并使用,不用的时候释放并让它回到缓存中。这就是池化技术,如果在程序中,需要频繁使用比较重的对象,那么一般都会利用池化技术提升性能。一般的池化技术基本上就是提前创建一堆对象,用的时候,拿去用,不用的时候,放回来。但是线程池无法这样设计,虽然从设计上,看上去可行,需要使用线程时,申请一个线程,使用完后,将这个线程放回池中。但是线程有个很致命的问题,线程创建之初,他所需要执行的流程就固定了,无法修改。所以一般的池化技术的设计思路就不可取了,于是Java对于线程池的设计,采用的生产者-消费者模型 生产者是使用线程池的我们,消费者就是线程池中的线程。

使用线程池的我们,通过线程池提供的API,将我们需要执行的任务加入到阻塞队列中,而每个线程都执行着固定的流程,即从阻塞队列中取任务,调用它们的run()方法。这就是Java对于线程池的设计。

不过在日常开发中,创建线程池的时候,推荐使用有界的阻塞队列,但是Java提供的Excutors.newxxxx()这些方法,传入的阻塞队列都是无界的即没有大小限制,很容易导致OOM(内存不够)


0个评论
点击登录,快来和大家讨论吧~
表情
图片
暂无评论
pandaer
作者分享
#AI应用开发 springAI是如何实现mcp的工具调用的,在springai中,工具调用被抽象成了一个toolcallback,无论是我们自己写的工具调用,还是mcp提供的,最终都会变成这个类的实例,然后再大模型返回的结果里,如果有工具调用,就会调用toolcallback的call方法,来执行真正的工具调用
4
#AI应用开发 今天学习了如何利用springAI来开发mcp server以及mcp client。开发mcp client很简单,只需要引入依赖,配置一下就好。开发一个mcp server也是一样 先要引入一个依赖,然后手动注入toolcallbackprovider这个bean就行了。需要利用tool注解来自定义需要对外提供的工具
4
#AI应用开发 今天学习了toolcall,本质还是给大模型提供上下文信息,让其生成调用。在传递给大模型的消息中有一个额外的字段叫做tools,里面定义了工具的声明。在模型的响应中有一个字段叫做tool_calls里面定义了要调用哪些工具。 工具的定义要清晰明了,参数结构尽可能的简单,不要试图在一次请求中拼装复杂的工具链。满足需求的情况下,越简单,越清晰越好
4
#AI应用开发 springAI实现短期记忆(会话内记忆)的实现是基于chatmemory来实现的,chatmemory这个接口专注于我要把那些消息交给大模型,而chatmemoryrepostory 这个接口专注的是会话中产生的消息怎么存? 存哪里? 是数据库还是内存?
4
#AI应用开发 springAI中 目前学习了两套api,一个是chatmodel,一个是chatclient。 chatmodel是封装了大模型提供商的chat请求,让我们可以很方便的调用模型,而不需要手写http请求。他提供了两个方法 一个是call,一个是stream 对应chat请求的两套模式,一个是非流式输出,一个是流式输出。所以这个更像是对大模型的抽象。 chatclient是基于chatmodel的封装,提供了更多的api,方便我们快速搭建相关的功能。 springAI 提供了prompt来抽象给chat的请求内容,不仅仅包含消息列表,还有一些模型配置,但是我感觉prompt这个名字不好,我宁愿叫chatrequest,也不叫prompt,因为一段小文本就是prompt
3
下载 APP