title: Sharing array of bins between threads
body: <p>I have an application that is multithreaded and working OK. However it's hitting lock contention issues (checked by snapshotting the java stack and seeing whats waiting).</p>
  
  <p>Each thread consumes objects off a list and either rejects each or places it into a Bin.</p>
  
  <p>The Bins are initially null as each can be expensive (and there is potentially a <strong>lot</strong> of them).</p>
  
  <p>The code that is causing the contention looks roughly like this:</p>
  
  <pre><code>public void addToBin(Bin[] bins, Item item) {
     Bin bin;
     int bin_index = item.bin_index
     synchronized(bins) {
        bin = bins[bin_index];
        if(bin==null) {
          bin = new Bin();
          bins[bin_index] = bin;
        }
     }
     synchronized(bin) {
       bin.add(item);
     }
  }
  </code></pre>
  
  <p>It is the synchronization on the <code>bins</code> array that is the bottleneck. </p>
  
  <p>It was suggested to me by a colleague to use double checked locking to solve this, but we're unsure exactly what would be involved to make it safe. The suggested solution looks like this:</p>
  
  <pre><code>public void addToBin(Bin[] bins, Item item) {
     int bin_index = item.bin_index
     Bin bin = bins[bin_index];
  
     if(bin==null) {
       synchronized(bins) {
          bin = bins[bin_index];
          if(bin==null) {
            bin = new Bin();
            bins[bin_index] = bin;
          }
       }
     }
  
     synchronized(bin) {
       bin.add(item);
     }
  }
  </code></pre>
  
  <p>Is this safe and/or is there a better/safer/more idiomatic way to do this?</p>