LinkedList Vs ConcurrentLinkedQueue

前端 未结 2 803
轮回少年
轮回少年 2021-02-09 21:13

Currently in a multithreaded environment, we are using a LinkedList to hold data. Sometimes in the logs we get NoSuchElementException while it is polling the linkedlist. Please

相关标签:
2条回答
  • 2021-02-09 21:32

    ConcurrentLinkedQueue [is] an unbounded, thread-safe, FIFO-ordered queue. It uses a linked structure, similar to those we saw in Section 13.2.2 as the basis for skip lists, and in Section 13.1.1 for hash table overflow chaining. We noticed there that one of the main attractions of linked structures is that the insertion and removal operations implemented by pointer rearrangements perform in constant time. This makes them especially useful as queue implementations, where these operations are always required on cells at the ends of the structure, that is, cells that do not need to be located using the slow sequential search of linked structures.

    ConcurrentLinkedQueue uses a CAS-based wait-free algorithm that is, one that guarantees that any thread can always complete its current operation, regardless of the state of other threads accessing the queue. It executes queue insertion and removal operations in constant time, but requires linear time to execute size. This is because the algorithm, which relies on co-operation between threads for insertion and removal, does not keep track of the queue size and has to iterate over the queue to calculate it when it is required.

    From Java Generics and Collections, ch. 14.2.

    Note that ConcurrentLinkedQueue does not implement the List interface, so it suffices as a replacement for LinkedList only if the latter was used purely as a queue. In this case, ConcurrentLinkedQueue is obviously a better choice. There should be no big performance issue unless its size is frequently queried. But as a disclaimer, you can only be sure about performance if you measure it within your own concrete environment and program.

    0 讨论(0)
  • 2021-02-09 21:41

    When you get a NoSuchElementException then this maybe because of not synchronizing properly. For example: You're checking with it.hasNext() if an element is in the list and afterwards trying to fetch it with it.next(). This may fail when the element has been removed in between and that can also happen when you use synchronized versions of Collection API.

    So your problem cannot really be solved with moving to ConcurrentLinkedQueue. You may not getting an exception but you've to be prepared that null is returned even when you checked before that it is not empty. (This is still the same error but implementation differs.) This is true as long as there is no proper synchronization in YOUR code having checks for emptiness and element retrieving in the SAME synchronized scope.

    There is a good chance that you trade NoSuchElementException for having new NullPointerException afterwards.

    This may not be an answer directly addressing your question about performance, but having NoSuchElementException in LinkedList as a reason to move to ConcurrentLinkedQueue sounds a bit strange.

    Edit

    Some pseudo-code for broken implementations:

    //list is a LinkedList
    if(!list.isEmpty()) {
        ... list.getFirst()
    }
    

    Some pseudo-code for proper sync:

    //list is a LinkedList
    synchronized(list) {
        if(!list.isEmpty()) {
            ... list.getFirst()
        }
    }
    

    Some code for "broken" sync (does not work as intended). This maybe the result of directly switching from LinkedList to CLQ in the hope of getting rid of synchronization on your own.

    //queue is instance of CLQ
    if(!queue.isEmpty()) { // Does not really make sense, because ...
        ... queue.poll() //May return null! Good chance for NPE here!
    }
    

    Some proper code:

    //queue is instance of CLQ
    element = queue.poll();
    
    if(element != null) {
       ...
    }
    

    or

    //queue is instance of CLQ
    synchronized(queue) {
        if(!queue.isEmpty()) {
            ... queue.poll() //is not null
        }
    }
    
    0 讨论(0)
提交回复
热议问题