Non-Blocking and Blocking Concurrent Queue Algorithm 高效的非阻塞队列实现

import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;

/**
 * Created by luochao on 14-1-4.
 */
public class ConcurrentQueue<Content> {
    private volatile Node<Content> head;
    private volatile Node<Content> tail;
    private final static AtomicReferenceFieldUpdater<ConcurrentQueue,Node> HEAD_UPDATER = AtomicReferenceFieldUpdater.newUpdater(ConcurrentQueue.class,Node.class,"head");
    private final static AtomicReferenceFieldUpdater<ConcurrentQueue,Node> TAIL_UPDATER= AtomicReferenceFieldUpdater.newUpdater(ConcurrentQueue.class,Node.class,"tail");
    private  boolean casHead(final Node<Content> expect,final Node<Content> update){
       return HEAD_UPDATER.compareAndSet(this,expect,update);
    }
    private boolean casTail(final Node<Content> expect,final Node<Content> update){
        return TAIL_UPDATER.compareAndSet(this,expect,update);
    }
    public ConcurrentQueue(){
        Node node = new Node(null,null);
        this.head = node;
        this.tail = node;

    }
    public void enqueue(Content content){
        Node newNode = new Node(null,content);
        while (true){
            Node t = tail;
            Node next = t.next;
            if(t == tail){//判断tail是否被修改 已经next一致性
                if(next == null){ //从队列末尾入列
                   if(t.casNext(null, newNode)){
                     casTail(tail,newNode);
                     return;
                   }
                }else {
                   casTail(tail,next);
                }
            }

        }
    }
    public boolean dequeue(Content content){
        Node h = head;
        Node t = tail;
        Node next = h.next;
        while (true){
            if(h == head){//double check 检查head是否一致
               if(h == t){//判断是否为空队列 Is queue empty or Tail falling behind?
                  if (next == null){
                      return false;
                  }
                  //Tail is falling behind. Try to advance it
                  casTail(t,next);
                  return true;
               }else{
                   if (casHead(h,next)){
                       return true;
                   }
               }
            }
        }

    }
    private static class Node<Content>{
            volatile Node next;
            Content value;

            Node(Node next, Content value) {
                this.next = next;
                this.value = value;
            }
            private  boolean casNext(Node<Content> expect,Node<Content> update){
                return NEXTUPDATE.compareAndSet(this,expect,update);
            }
            //字段更新器 param 1 字段所在类  2 更新字段的值 3 字段名称 基于cas
            private static final AtomicReferenceFieldUpdater<Node,Node> NEXTUPDATE =
                    AtomicReferenceFieldUpdater.newUpdater(Node.class,Node.class,"next");

    }
}

  Simple, Fast, and Practical Non-Blocking and Blocking  Concurrent Queue Algorithms

 refer:http://www.cs.rochester.edu/u/michael/PODC96.html

在Verilog中,信号在阻塞(`=`)和非阻塞(`<=`)方式下都被赋值会导致可预测的行为,因为这两种赋值方式有同的时序语义。以下是解决该问题的方法: #### 明确设计意图,统一赋值方式 根据设计的时序要求,选择合适的赋值方式。通常,在组合逻辑中使用阻塞赋值,在时序逻辑中使用非阻塞赋值。 **组合逻辑示例**: ```verilog module combinational_logic ( input wire a, input wire b, output reg out ); always @(*) begin out = a & b; // 组合逻辑使用阻塞赋值 end endmodule ``` **时序逻辑示例**: ```verilog module sequential_logic ( input wire clk, input wire d, output reg q ); always @(posedge clk) begin q <= d; // 时序逻辑使用非阻塞赋值 end endmodule ``` #### 检查代码逻辑,避免混淆 仔细检查代码,确保没有在同一个`always`块或同的`always`块中对同一个信号同时使用阻塞非阻塞赋值。如果发现这种情况,需要对代码进行重构。 **错误示例**: ```verilog module wrong_example ( input wire clk, input wire d, output reg q ); always @(posedge clk) begin q <= d; // 非阻塞赋值 q = d; // 阻塞赋值,错误! end endmodule ``` **修正后的示例**: ```verilog module correct_example ( input wire clk, input wire d, output reg q ); always @(posedge clk) begin q <= d; // 统一使用非阻塞赋值 end endmodule ``` #### 使用同的信号名 如果确实需要在同的逻辑中对类似的信号进行操作,可以使用同的信号名,避免对同一个信号进行同方式的赋值。 ```verilog module different_names ( input wire clk, input wire d, output reg q ); reg temp; always @(*) begin temp = d; // 组合逻辑使用阻塞赋值 end always @(posedge clk) begin q <= temp; // 时序逻辑使用非阻塞赋值 end endmodule ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值