自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(18)
  • 收藏
  • 关注

转载 Log4j2日志异步打印优化分析

经过上文分析,我们可以将Log4j2的异步日志打印优化总结如下:1.在日志可以丢弃的情况下,推荐使用和的组合配置;2.不要在生产环境使用可以直接与中间件交互的的Appender,如KafkaAppender。

2024-01-22 09:20:58 404 1

转载 高性能MySQL实战(一):表结构

MySQL 总是为 CHAR 类型分配所定义长度的空间,所以它是固定长度的,它相比于 VARCHAR 在面对经常修改的数据时表现更好,因为固定长度的列不容易出现内存碎片,而且对于 CHAR(1) 这种非常短的列,它要比 VARCHAR(1) 更高效,因为前者只占用 1 个字节的空间,后者占用 2 个字节(其中 1 字节记录长度)。一般来说,要尽量使用能够正确存储和表示数据的最小数据类型,更小的数据类型通常更快,因为它们占用的磁盘、内存和CPU缓存的空间更少,并且处理时需要的CPU周期也更少。

2023-08-09 09:20:37 145 1

原创 JMH使用

指定某项参数的多种情况,特别适合用来测试一个函数在不同的参数输入的情况下的性能,只能作用在字段上,使用该注解必须定义 @State 注解。进行 fork 的次数,可用于类或者方法上。如果 fork 数是 2 的话,则 JMH 会 fork 出两个进程来进行测试。JMH测试结果是一个json串,我们也可以通过一些工具进行可视化直观展示。必须标示在@State注解的类内部,表示初始化操作。必须表示在@State注解的类内部,表示销毁操作。实际调用方法所需要配置的一些基本测试参数。每个测试进程的测试线程数。

2023-07-21 17:12:03 142 1

原创 CompletableFuture

thenCompose thenComposeAsync:某个任务执行完成后执行的动作,Function<?whenComplete whenCompleteAsync:某个任务执行完成后执行的动作,BiConsumer<?thenApply thenApplyAsync:某个任务执行完成后执行的动作,Function<?runAfterBoth runAfterBothAsync:两个任务都执行完成后,执行下一步操作,没有入参,也没有返回值。以Async结尾的方法,都是异步的,否则是同步的。

2023-07-21 15:59:03 150 1

原创 java虚拟线程

要注意虚拟线程并不是用来直接取代平台线程的,虚拟线程是运行在平台线程之上的,一个平台线程可以对应多个虚拟线程,同时一个平台线程还是一一对应内核线程,因此上面的架构就变成了如下,一个 VT 代表一个虚拟线程。Java 中的线程跟操作系统的内核线程是一对一的,Java 线程的调度其实是依赖操作系统的内核线程的,这就导致了我们的线程切换和运行就需要进行上下文切换以及消耗大量的系统资源。JDK 的调度器没有直接将虚拟线程分配给系统线程,而是将虚拟线程分配给平台线程(这是前面提到的虚拟线程的 M:N 调度)。

2023-07-03 18:16:36 1958 2

原创 线程池线程执行异常后会怎么样

在案例二中,当thread-2执行抛出异常后,线程池会将这个异常线程移除,并创建一个新的线程放入线程池,如果采用默认策略,新创建的线程id会在最大线程id上进行自增加一,因为案例中在thread-2执行时最大的线程id=2,所以此时线程池新创建的线程是thread-3,此时线程池中的线程数量依然是3个,所以在下一个任务执行时会在新建一个线程,就是thread-4。线程池一共创建了4个线程,当num=3的时候thread-2发生了异常,thread-2发生异常后不在执行其他的任务。

2023-07-03 17:50:02 345 1

原创 Golang基础

这种方式在于第一次调用的时候会执行上面的代码片段,后面只是保存了这个函数的句柄,然后可以一直调用这个匿名函数。注意,这里需要传入指针,因为它不是一个引用类型。不同,它支持多返回值,为我们的使用带来了很多便利。通过结构体 + 方法的形式实现,注意方法传入的可以是引用也可以是值。这是类似于一种最上层异常捕获的机制,在程序的入口处捕获所有的异常。的永远是文件夹,遵循以上规则则意味着文件夹的名称即为模块名。我建议使用第二种,更便捷自带类型转换,还可以给默认值,非常好。的异常处理涉及的很简单,也往往为人所诟病。

2023-06-30 15:48:18 146

原创 分布式锁思考

但是由于我们的系统都是分布式的,这个锁一般不会只放在某个进程中,我们会借用第三方存储,比如 Redis 来做这种分布式锁。我们平时说的分布式锁,一般指的是在不同服务器上的多个线程中,只有一个线程能抢到一个锁,从而执行一个任务。但是有这个超时时间我们又遇上了问题,超时时间设置多久合适呢?当然要设置的比 DoJob 消耗的时间更长,否则的话,在任务还没结束的时候,锁就被释放了,还是有可能导致并发任务的存在。这个问题,我们面对的除了程序的bug之外,还有网络的不稳定,进程被杀死,服务器被down机等。

2023-06-29 18:50:09 52 1

原创 JVM中的指针压缩

因为64位JVM的每一个native指针都占用8个字节,而在32位JVM中只有4字节,加载这些额外的字节会影响内存的占用,且当内存增大了之后,GC停顿时间自然而然的也会跟着变大,因为内存中有更多的垃圾需要来回收了。至于为什么要对内存地址进行左右位移操作,是因为内存进行 8bytes 边界对齐后,内存地址的后三位都是 0,根据这个规则,就可以在存储的时候舍弃后面的三位,读取的时候再加上这三位。64位JVM,提供了更大的寻址空间,也引发内存占用更大,GC停顿时间变大的问题,指针压缩技术就应运而生。

2023-06-27 14:16:44 943

转载 Java并发-理论基础

由上面的分析可知,当线程1执行 i =10这句时,会先把i的初始值加载到CPU1的高速缓存中,然后赋值为10,那么在CPU1的高速缓存当中i的值变为10了,却没有立即写入到主存当中。由于 Java 语言天生就具备多线程特性,线程对立这种排斥多线程的代码是很少出现的,而且通常都是有害的,应当尽量避免。由于CPU分时复用(线程切换)的存在,线程1执行了第一条指令后,就切换到线程2执行,假如线程2执行了这三条指令后,再切换会线程1执行后续两条指令,将造成最后写到内存中的i值是2而不是3。

2023-06-27 13:58:54 247

原创 TransmittableThreadLocal

在使用线程池等会池化复用线程的执行组件情况下,提供ThreadLocal值的传递功能,解决异步执行时上下文传递的问题。

2023-06-26 13:53:20 534 1

原创 TransmittableThreadLocal内存泄漏问题排查

通过上图可以看到第一次执行异步任务的时候能够获取到值,之后主线程进行remove操作,主线程获取不到为空,第二个异步任务执行的时候能够获取到值。执行第二次异步任务的时候,获取值为空是因为异步任务用TtlRunnable修饰,用它修饰的话,执行任务前会将用父线程也就是主线程的上下文信息给子线程,这个时候主线程已经被清空,所以展示为空。执行异步任务的时候,会初始化线程,初始化线程的特性会子线程也继承父线程;可以看到最后一个异步任务也拿不到值了,说明异步线程的上下文也被清空了。这个线程绑定的值有值了。

2023-06-26 10:28:26 363 1

原创 多线程执行

2、Exchanger(两个线程无序)1、队列+park+volatile。批次之间结果无依赖,无返回值。

2023-06-21 11:52:39 211

原创 synchronized

线程安全是并发编程中重要的一部分,在Java语言中,有一个关键字——synchronized可以保证线程的安全,它可以保证在同一时刻只有一个线程执行某方法,还可以让一个线程中的共享数据的变化被其他线程所看到。作用于当前实例加锁,进入同步代码前要获得当前实例的锁给当前类加锁,会作用于类的所有对象实例,进入同步代码前需要获得当前class的锁。因为静态成员不属于任何一个实例对象,是类成员。

2023-06-17 10:49:08 92 1

原创 Disruptor

Disruptor是一个优秀的并发框架,可以实现单个或多个生产者生产消息,单个或多个消费者消息,且消费者之间可以存在消费消息的依赖关系,体现了去掉了锁,采用CAS算法,同时内部通过环形队列实现有界队列。RingBuffer:是一个环(首尾相连的环),用做在不同上下文(线程)间传递数据的buffer,拥有一个序号,这个序号指向数组中下一个可用元素。EventHandler和WorkerHandler。

2023-06-17 09:37:23 209 1

原创 常用语言的线程模型(Java、go、C++、python3)

在目前的线程模型中,有1:1、M:1、M:N多种线程模型,具体采用哪种线程模型也和硬件和操作系统的支持程度有关,像诞生比较早的语言,普通采用M:1、1:1线程模型,像c++、java。而新诞生不久的go语言,采用的是M:N线程模型,在多线程的支持上更加强大。

2023-06-16 19:57:31 306 1

原创 DDD代码结构

权限验证—>对象创建/获取—>领域服务(多个)—>仓储保存—>外部通知(可以为jsf或事件)?只产生接入异常,例如数据校验,对应 HTTP 状态码 400、403、415 等。数据权限放到这层(比如只允许删除自己创建的商品),因为数据权限涉及业务规则。关心处理完一个完整的业务,业务可以分为业务用例服务和系统用例服务。领域层做业务逻辑处理、业务规则验证,领域层均为内存级对象处理。不关心谁来,不关心场景完整的业务,关心当前上下文的业务完整。该层只负责业务编排,对象转换,实际业务逻辑由领域层完成。

2023-06-05 16:50:34 232 1

原创 1、Mybatis的parameterType造成线程阻塞

1、在使用 paramType 时,xml 配置的类型需要与 Java 代码中传入的一致,使用 Mybatis 预加载时的类型缓存。2、在使用 paramType 时,避免使用 java.util.HashMap 类型,避免 SQL 执行时解析 TypeHandler。3、在接受返回值时,使用 resultMap,提前映射返回值,减少 TypeHandler 解析。

2023-06-02 09:30:04 108

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除