一.锁的缺点Disruptor怎么解决

悲观锁是将并行执行的代码串行化,其他线程还需要尝试着获取锁,它将比单线程执行更加慢,乐观锁要比悲观锁快上好多,但是它需要涉及操作系统。Disruptor中不使用锁,为了保证线程的安全它采用了CAS(Compare And Set/Swap)操作,它不涉及操作系统,它们直接在CPU上操作。但是它也不是没有代价。

Disruptor论文中讲述了我们所做的一个实验。这个测试程序调用了一个函数,该函数会对一个64位的计数器循环自增5亿次。当单线程无锁时,程序耗时300ms。如果增加一个锁(仍是单线程、没有竞争、仅仅增加锁),程序需要耗时10000ms,慢了两个数量级。更令人吃惊的是,如果增加一个线程(简单从逻辑上想,应该比单线程加锁快一倍),耗时224000ms。使用两个线程对计数器自增5亿次比使用无锁单线程慢1000倍。并发很难而锁的性能糟糕。在上面的试验中,单线程无锁耗时300ms,单线程有锁耗时10000ms,单线程使用CAS耗时5700ms。所以它比使用锁耗时少,但比不需要考虑竞争的单线程耗时多。

Disruptor中存在俩种策略一个是SingleThreadedStrategy(单线程策略)另一个是MultiThreadedStrategy(多线程策略)。在添加单个生产者时为什么不用多线程策略?当然可以使用这种策略,但是多线程策略中使用了AtomicLong,而单线程的使用long,没有锁也没有CAS,所以单线程版本会很快。
如果只有一个生产证,系统中的每一个序列号只会由一个线程写入,这就不需并发控制,存在多个生产者是序号会被多线程竞争写入。

二.队列为什么不能胜任工作

为什么队列底层要用RingBuffer来实现,队列和检点的RingBuffer只有头和尾俩个指针。如果生产者往队列里放东西,尾指针在多个线程中会发生冲突。如果有多个消费者,头指针就会产生竞争。队列的大小也会存在竞争。
队列的头尾指针和大小常常在一个缓存行(cahceLine)中,就有伪共享(false sharing)的问题,
详情请参见