java无锁提高性能_GitHub - fengwk/concurrent-queue: 该库提供了一些线程安全的无锁的高性能队列的Java实现以便学习和参考。...

ConcurrentQueue

该库提供了一些线程安全的无锁的高性能队列的Java实现以便学习和参考。

介绍

WaitingQueue

在并发且无锁场景下使用类似Object.wait()和Object.notify()这样的同步机制可能是不安全的。

例如下边的场景中的执行顺序可能是这样的:step1->step3->step4->step2。

这样一来Thread1将错过Thread2的唤醒从而陷入永久的等待。

init:

condition = false

Thread1:

while (!condition) { // step1

wait // step2

}

Thread2:

condition = true // step3

notify // step4

WaitingQueue是为了避免上述情况而设计的,它将wait分为两个步骤WaitingQueue.prepareWait和WaitingNode.await。

在condition检查前先使用prepareWait入队这个可能因检查失败而被挂起的线程Thread1,这样一来Thread1永远不会错过被Thread2唤醒的机会,当然实现中还需要依赖另一个安全挂起和唤醒的组件,例如LockSupport。

init:

boolean condition = false;

WaitingQueue wq = new WaitingQueue();

Thread1:

for (;;) {

WaitingNode wn = wq.prepareWait();

if (condition) {

break;

}

wn.await();

}

Thread2:

condition = true;

wq.signal();

语义保证:

w表示调用挂起的线程数量。

s表示唤醒的线程数量。

x表示WaitingNode.await调用次数。

y表示WaitingQueue.signal调用次数。

WaitingNode.await调用,当前线程将挂起,x++,w++。

WaitingQueue.signal调用,若有已被挂起或已prepare将来会被挂起的线程,则保证必然能唤醒其中已被挂起或将来被挂起的最先者,已被唤醒过的线程除非重新调用WaitingNode.await否则不会被再次唤醒(在当前版本的实现中这个语义是逻辑上正确的),y++,s++。

若某一时刻x==y,则w==s。

RingBufferBlockingQueue

通过RingBufferBlockingQueue.enqueue(Object)入队元素,通过RingBufferBlockingQueue.dequeue()出队元素。

当队列已满时调用RingBufferBlockingQueue.enqueue(Object)的线程将被阻塞,当队列为空时调用RingBufferBlockingQueue.dequeue()的线程将被阻塞。

该缓冲队列可以用于生产消费者模式的实现中,可使用命令模式解耦生产消费者,且使用缓冲区能够有效消除生产快消费慢的速度差异。

使用

WaitingQueue

public class WaitingQueue {

/**

* 准备一个等待节点。

*

* @return

*/

public WaitingNode prepareWait()

/**

* 若有已被挂起或已prepare将来会被挂起的线程,则保证必然能唤醒其中已被挂起或将来被挂起的最先者,已被唤醒过的线程除非重新调用{@link WaitingNode#await}否则不会被再次唤醒。

*/

public void signal()

}

public class WaitingNode {

/**

* 挂起当前线程直至收到一个当前节点prepare完成后的{@link WaitingQueue#signal()}通知。

*/

public void await() throws InterruptedException

}

init:

boolean condition = false;

WaitingQueue wq = new WaitingQueue();

Thread1:

for (;;) {

WaitingNode wn = wq.prepareWait();

if (condition) {

break;

}

wn.await();

}

Thread2:

condition = true;

wq.signal();

RingBufferBlockingQueue

public class RingBufferBlockingQueue {

/**

* 入队元素,当队列已满时调用线程将被阻塞。

*

* @param element

* @throws InterruptedException

*/

public void enqueue(E element) throws InterruptedException

/**

* 出队元素,当队列为空时调用线程将被阻塞。

*

* @return

* @throws InterruptedException

*/

public E dequeue() throws InterruptedException

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值