java Thread-safe LRUCache implementation What is best way to implement thread-safe LRUCache in java?
Please review this one.
Is there any better approach which can be taken here?

package cache;

import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

public class  LRUCache&lt;K,V&gt; {

    private  ConcurrentLinkedQueue&lt;K&gt; concurrentLinkedQueue = new ConcurrentLinkedQueue&lt;K&gt;();

    private  ConcurrentHashMap&lt;K,V&gt; concurrentHashMap = new ConcurrentHashMap&lt;K, V&gt;();

    private ReadWriteLock readWriteLock = new ReentrantReadWriteLock();

    private Lock readLock = readWriteLock.readLock();

    private Lock writeLock = readWriteLock.writeLock();

    int maxSize=0;

    public LRUCache(final int MAX_SIZE){
        this.maxSize=MAX_SIZE;
    }

    public V getElement(K key){

        readLock.lock();
        try {
        V v=null;
          if(concurrentHashMap.contains(key)){
              concurrentLinkedQueue.remove(key);
              v= concurrentHashMap.get(key);
                concurrentLinkedQueue.add(key);
          }


        return v;
        }finally{
            readLock.unlock();
        }
    }

    public V removeElement(K key){
         writeLock.lock();
         try {
        V v=null;
        if(concurrentHashMap.contains(key)){
        v=concurrentHashMap.remove(key);
            concurrentLinkedQueue.remove(key);
        }

        return v;
         } finally {
             writeLock.unlock();
         }
    }

    public V addElement(K key,V value){
        writeLock.lock();
        try {
        if(concurrentHashMap.contains(key)){
             concurrentLinkedQueue.remove(key);
        }
        while(concurrentLinkedQueue.size() &gt;=maxSize){
             K queueKey=concurrentLinkedQueue.poll();
             concurrentHashMap.remove(queueKey);
        }
        concurrentLinkedQueue.add(key);
        concurrentHashMap.put(key, value);

        return value;
        } finally{
            writeLock.unlock();
        }
    }
}
Advice 1

This implementation is not thread safe. For example, if two threads invoked getElement(key1) simultaneously, they may runs to concurrentLinkedQueue.add(key) at same times(they both performed delete and get, but delete will fail the second time or just do nothing), then two same keys will be added.

Advice 2

Maybe capacity is more suitable than maxSize.

Advice 3

LinkedHashMap is often used as LRU cache.