p.casNext诡异问题排查

2020-04-17  本文已影响0人  Sun_1a09

idea debug/run返回不同结果

在ConcurrentLinkedQueue源码调试中发现run/debug这两个问题出现不同结果的问题 。 相当诡异!!!
随后只能将代码抽离出来进行排查。

    public boolean offer(E e) {
        final Node<E> newNode = new Node<E>(e);
        Node<E> t = tail, p = t;
        Node<E> q = p.next;
        if (q == null) {
            if(p.casNext(null,newNode)){
                System.out.println(p.next ==p);  //1
                if (p != t) // hop two nodes at a time//2
                    casTail(t, newNode);  // Failure is OK.
                return true;
            }
        }

发现只要断点打在1处就有问题 p.next =p 为true 然而在点2处正常。
可能有一下问题:

验证思路

在可变状态方法中增加调试信息

结果

发现first()被多次调用。为了更好了解调用信息 加上调用信息 代码如下:

       System.out.println("-----------------------------------------------------------------");
       StackTraceElement stack[] = Thread.currentThread().getStackTrace();
       for (int i = 0; i < stack.length; i++) {
           System.out.println(stack[i].getClassName() + " -->" + stack[i].getMethodName()+" " +stack[i].getLineNumber() );
       }
       System.out.println("-----------------------------------------------------------------");

debug时日志打印


java.lang.Thread -->getStackTrace 1559
com.ly.lock.ConcurrentLinkedQueue -->first 188
com.ly.lock.ConcurrentLinkedQueue -->isEmpty 214
com.ly.lock.ConcurrentLinkedQueue -->offer 103
com.ly.lock.ConcurrentLinkedQueue -->main 773



java.lang.Thread -->getStackTrace 1559
com.ly.lock.ConcurrentLinkedQueue -->first 188
com.ly.lock.ConcurrentLinkedQueue -->size 235
com.ly.lock.ConcurrentLinkedQueue -->offer 103
com.ly.lock.ConcurrentLinkedQueue -->main 773



java.lang.Thread -->getStackTrace 1559
com.ly.lock.ConcurrentLinkedQueue -->first 188
com.ly.lock.ConcurrentLinkedQueue -->toArray 374
com.ly.lock.ConcurrentLinkedQueue -->offer 103
com.ly.lock.ConcurrentLinkedQueue -->main 773


结论

结果很清晰 在debug时 IDE会自动调用toArray、size 、isEmpty方法从而调用first()方法 查看first会发现 该方法会重新设置头结点 h.lazySetNext(h); 所以造成debug,RUN模式结果不一致这一诡异情况。

上一篇下一篇

猜你喜欢

热点阅读