Thread safety in multithreaded access to LinkedList

℡╲_俬逩灬. 提交于 2019-12-10 22:25:20

问题


My application needs to keep an access log of requests to a certain resource and multiple threads will be recording log entries. The only pertinent piece of information is the timestamp of the request and the stats being retrieved will be how many requests occurred in the last X seconds. The method that returns the stats for a given number of seconds also needs to support multiple threads.

I was thinking of approaching the concurrency handling using the Locks framework, with which I am not the most familiar, hence this question. Here is my code:

import java.util.LinkedList;
import java.util.concurrent.locks.ReentrantLock;

public class ConcurrentRecordStats 
{
    private LinkedList<Long> recLog;
    private final ReentrantLock lock = new ReentrantLock();

    public LinkedConcurrentStats()
    {
        this.recLog = new LinkedList<Long>();
    }

    //this method will be utilized by multiple clients concurrently
    public void addRecord(int wrkrID)
    {
        long crntTS = System.currentTimeMillis();
        this.lock.lock();
        this.recLog.addFirst(crntTS);
        this.lock.unlock();
    }

    //this method will be utilized by multiple clients concurrently
    public int getTrailingStats(int lastSecs)
    {
        long endTS = System.currentTimeMillis();
        long bgnTS = endTS - (lastSecs * 1000);

        int rslt = 0;

        //acquire the lock only until we have read
        //the first (latest) element in the list
        this.lock.lock();

        for(long crntRec : this.recLog)
        {
            //release the lock upon fetching the first element in the list
            if(this.lock.isLocked()) 
            {
                this.lock.unlock();
            }

            if(crntRec > bgnTS)
            {
                rslt++;
            }
            else
            {
                break;
            }
        }

        return rslt;
    }
}

My questions are:

  1. Will this use of ReentrantLock insure thread safety?
  2. Is it needed to use a lock in getTrailingStats?
  3. Can I do all this using synchronized blocks? The reason I went with locks is because I wanted to have the same lock in both R and W sections so that both writes and reading of the first element in the list (most recently added entry) is done a single thread at a time and I couldn't do that with just synchronized.
  4. Should I use the ReentrantReadWriteLock instead?

回答1:


The locks can present a major performance bottleneck. An alternative is to use a ConcurrentLinkedDeque: use offerFirst to add a new element, and use the (weakly consistent) iterator (that won't throw a ConcurrentModificationException) in place of your for-each loop. The advantage is that this will perform much better than your implementation or than the synchronizedList implementation, but the disadvantage is that the iterator is weakly consistent - thread1 might add elements to the list while thread2 is iterating through it, which means that thread2 won't count those new elements. However, this is functionally equivalent to having thread2 lock the list so that thread1 can't add to it - either way thread2 isn't counting the new elements.



来源:https://stackoverflow.com/questions/17847935/thread-safety-in-multithreaded-access-to-linkedlist

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!