yankj12 / blog

技术研究、管理实践、其他的一些文章
MIT License
1 stars 2 forks source link

disruptor整理 #43

Open yankj12 opened 6 years ago

yankj12 commented 6 years ago

disruptor入门demo

Disruptor快速入门 架构师养成记--15.Disruptor并发框架

java 内部工作线程介绍 我们能看见HelloWorld实际上创建了如下线程: "Low Memory Detector" "CompilerThread0" "Signal Dispatcher" "Finalizer" "Reference Handler" "main" "VM Thread" "VM Periodic Task Thread"

由于我手头上的资料也不是很全,简单说明一下都是干什么用的。 "Low Memory Detector" 负责对可使用内存进行检测,如果发现可用内存低,分配新的内存空间。 "CompilerThread0" 用来调用JITing,实时编译装卸class。 "Signal Dispatcher" 负责分发内部事件。 "Finalizer" 负责调用Finalizer方法。 "Reference Handler" 负责处理引用。 "main" 是主线程。 "VM Thread", "VM Periodic Task Thread"从名字上看是虚机内部线程。(这两个在Jconsole下看不见) 我们还可以看出实际上只有"main","VM Thread","Low Memory Detector" 在工作。 而"Low Memory Detector" ,"CompilerThread0","Signal Dispatcher","Finalizer","Reference Handler"都是daemo进程。

Java Thread State 分析(写的很好,对于jvm线程分析很有帮助)

  1. 线程状态为“waiting for monitor entry”: 意味着它 在等待进入一个临界区 ,所以它在”Entry Set“队列中等待。 此时线程状态一般都是 Blocked:
    • java.lang.Thread.State: BLOCKED (on object monitor)
  1. 线程状态为“waiting on condition”: 说明它在等待另一个条件的发生,来把自己唤醒,或者干脆它是调用了 sleep(N)。 此时线程状态大致为以下几种:

    • java.lang.Thread.State: WAITING (parking):一直等那个条件发生;
    • java.lang.Thread.State: TIMED_WAITING (parking或sleeping):定时的,那个条件不到来,也将定时唤醒自己。
  2. 如果大量线程在“waiting for monitor entry”: 可能是一个全局锁阻塞住了大量线程。 如果短时间内打印的 thread dump 文件反映,随着时间流逝,waiting for monitor entry 的线程越来越多,没有减少的趋势,可能意味着某些线程在临界区里呆的时间太长了,以至于越来越多新线程迟迟无法进入临界区。

  3. 如果大量线程在“waiting on condition”: 可能是它们又跑去获取第三方资源,尤其是第三方网络资源,迟迟获取不到Response,导致大量线程进入等待状态。 所以如果你发现有大量的线程都处在 Wait on condition,从线程堆栈看,正等待网络读写,这可能是一个网络瓶颈的征兆,因为网络阻塞导致线程无法执行。

jstack Dump 日志文件中的线程状态 dump 文件里,值得关注的线程状态有:

jdk工具之jstack(Java Stack Trace) jstack [ option ] pid 基本参数: -F 当’jstack [-l] pid’没有响应的时候强制打印栈信息 -l 长列表. 打印关于锁的附加信息,例如属于java.util.concurrent的ownable synchronizers列表. -m 打印java和native c/c++框架的所有栈信息. -h | -help打印帮助信息 pid 需要被打印配置信息的java进程id,可以用jps工具查询. [1]

Locked ownable synchronizers(转)

disruptor指定等待策略WaitStrategy

disruptor指定等待策略WaitStrategy

指定等待策略
Disruptor 定义了 com.lmax.disruptor.WaitStrategy 接口用于抽象 Consumer 如何等待新事件,这是策略模式的应用。
Disruptor 提供了多个 WaitStrategy 的实现,每种策略都具有不同性能和优缺点,根据实际运行环境的 CPU 的硬件特点选择恰当的策略,并配合特定的 JVM 的配置参数,能够实现不同的性能提升。
例如,BlockingWaitStrategy、SleepingWaitStrategy、YieldingWaitStrategy 等,其中,
BlockingWaitStrategy 是最低效的策略,但其对CPU的消耗最小并且在各种不同部署环境中能提供更加一致的性能表现;
SleepingWaitStrategy 的性能表现跟 BlockingWaitStrategy 差不多,对 CPU 的消耗也类似,但其对生产者线程的影响最小,适合用于异步日志类似的场景;
YieldingWaitStrategy 的性能是最好的,适合用于低延迟的系统。在要求极高性能且事件处理线数小于 CPU 逻辑核心数的场景中,推荐使用此策略;例如,CPU开启超线程的特性。

WaitStrategy BLOCKING_WAIT = new BlockingWaitStrategy();
WaitStrategy SLEEPING_WAIT = new SleepingWaitStrategy();
WaitStrategy YIELDING_WAIT = new YieldingWaitStrategy();

//----------------------------------
EventFactory<LongEvent> eventFactory = new LongEventFactory();
ExecutorService executor = Executors.newSingleThreadExecutor();
int ringBufferSize = 1024 * 1024; // RingBuffer 大小,必须是 2 的 N 次方;

Disruptor<LongEvent> disruptor = new Disruptor<LongEvent>(eventFactory,
                ringBufferSize, executor, ProducerType.SINGLE,
                new YieldingWaitStrategy());

EventHandler<LongEvent> eventHandler = new LongEventHandler();
disruptor.handleEventsWith(eventHandler);

disruptor.start();

高并发数据结构Disruptor解析-5 WaitStrategy

相关资料

关于Disruptor添加任务阻塞的问题 从构建分布式秒杀系统聊聊Disruptor高性能队列 使用Disruptor BlockingWaitStrategy遭遇死锁dead lock Dead lock observed in BlockingWaitStrategy in Log 4J Disruptor中遇到的坑

一起聊聊Disruptor 这个内容写的比较多,推荐阅读

disruptor-github文章

Introduction Getting-Started Frequently-Asked-Questions