title: Can I synchronize method by parameter
body: <p>Can I synchronize method by parameter? </p>
  
  <p>For example - I get person to some method and I want to do some operation for person, but if few thread call this method for the same person I want to do it one by one.</p>
  
  <pre><code>private void dosomething(Long id, Person person) {
      dosomethingelse(id, person);
  }
  </code></pre>
  
  <p>How to call dosomethingelse (id, person) only for the same id one by one? but I want that this code for different id-s can be called multithreadly</p>
  
  <p>I wrote this code, but maybe something wrong here or something can be better.</p>
  
  <pre><code>public static class LatchByValue &lt;T&gt; {
      public void latch(T value, ConsumerWithException&lt;T&gt; consummer) throws Exception {
          CountDownLatch latch = new CountDownLatch(1);
          try {
              CountDownLatch previousLatch = null;
              // we are checking if another thread is already calling this method with the same id
              // if sync has CountDownLatch so another thread is already calling this method 
              // or we put our latch and go on
              while ((previousLatch = sync.putIfAbsent(value, latch)) != null) {
                  try {
                      // we are waiting for another thread, we are waiting for all threads that put their latch before our thread
                      previousLatch.await();
                  } catch (InterruptedException e) {
                      return;
                  }
              }
              consummer.accept(value);
          } finally {
              latch.countDown();
              sync.remove(value, latch);
          } 
      }
      private ConcurrentHashMap&lt;T, CountDownLatch&gt; sync = new ConcurrentHashMap&lt;&gt;();
  }
  </code></pre>
  
  <p>Example:</p>
  
  <pre><code>LatchByValue&lt;Long&gt; latch = new LatchByValue&lt;&gt;();
  
  private void dosomething(Long id, Person person) {
       latch.latch(
          id,
          currentId -&gt; { dosomethingelse(currentId, person); }
       );
  }
  </code></pre>