Assume that we have a method doSomething(String input) and we want to run it synchronized by different inputs.
It means that running doSomething(A) should block any consecutive calls of doSomething(A)  until the first one is completed BUT should not block doSomething(B) or doSomething(C).
So i've created a wrapper method to achieve this goal. It creates objects based on input value and places locks on them and keeps a reference to them in a list.
private static final ArrayList<String> runningTasks  = new ArrayList<>();
public void doSomethingSyncedByInput(String input) {
    // Create a lock or load an already created lock from the list.
    // (Yeah, it's a race condition but forget about it. It's just an example.)
    String lock = new String(input);
    if(runningTasks.contains(input)){
        // get currently available lock object
        lock = runningTasks.get(runningTasks.indexOf(input));
    }else {
        // add a reference on tasks list
        runningTasks.add(lock);
    }
    synchronized (lock) {
        doSomething(input);
    }
}
It actually works; but it's not a totally thread-safe solution as ArrayList is not thread-safe. The contents of ArrayList is not volatile and according to documentation, adding and removing items on the list is not reflected on other threads instantly.
Note that this implementation is not synchronized. If multiple threads access an
ArrayListinstance concurrently, and at least one of the threads modifies the list structurally, it must be synchronized externally.
A well known thread safe variant of ArrayList is CopyOnWriteArrayList (which makes a copy of the elements and re-sets the inner volatile field holding elements to be sure to have latest version of the list on all other threads instantly). As the name yields, it COPIES each one of the list items on adding a new item to the list and it means the references to the actual objects that got the lock on, would be lost and the code will be broken.
So I need a datatype which holds a list of objects and doesn't copy or change objects in favor of concurrency support. I could use String.intern() functionality but it brings a lot of potential problems especially on mobile platforms.
Any ideas?
Or, do you know any bulletproof implementations available to use?
I'm on Android platform by the way.
UPDATE:
I've reached a solution by myself. Check out my own answer. Comments are welcomed.
 
     
    