Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>I think what you mean is non-blocking and reentrant.</p> <p><strong>edit:</strong> (replaces my original because this is much better)</p> <p>A thread-based option that is actually pretty performant just came to mind (at least more performant than your original). If you created a weak hash map with a thread object as the "Key" and as the "Value" put an object with the ability to manufacture a series of, say, 1000 numbers from a specific range.</p> <p>That way you assign each thread it's own 1000 number range to allocate from. When the object runs out of numbers, have it return an invalid number (0?) and you'll know that you have to allocate a new range to that object.</p> <p>There would be no synchronizing anything anywhere (edit: whoops, was a little wrong. See below), the weak hash map would automatically free threads that were destroyed (no special maintenance) and the slowest part would be a single hash lookup of the thread which is actually very quick.</p> <p>get the current running thread with:</p> <pre><code>Thread currThread=Thread.getCurrentThread(); </code></pre> <p>Also I could be wrong and you could just need to make the method synchronized, then this would work:</p> <pre><code>int n=-1; synchronized int getNegativeNumber() { return n--; } </code></pre> <p>I went ahead and wrote it (sometimes this stuff gets stuck in my head until I do it, and as long as I did it anyway, I might as well post it). Untested and all, but I'm pretty sure it should be close if not operational right out of the box. Just one class with one static method to call to get a unique negative number. (Oh, and I did need some synchronization but it will only be used .001% of the time).</p> <p>Wish there was a way to create a linked code block instead of inline like this without going off site--sorry about the length.</p> <pre><code>package test; import java.util.WeakHashMap; public class GenNumber { // Static implementation goes first. private static int next = -1; private static final int range = 1000; private static WeakHashMap&lt;Thread, GenNumber&gt; threads = new WeakHashMap&lt;Thread, GenNumber&gt;(); /** * Generate a unique random number quickly without blocking * * @return the random number &lt; 0 */ public static int getUniqueNumber() { Thread current = Thread.currentThread(); int next = 0; // Have to synchronize some, but let's get the very // common scenario out of the way first without any // synchronization. This will be very fast, and will // be the case 99.9% of the time (as long as range=1000) GenNumber gn = threads.get(current); if (gn != null) { next = gn.getNext(); if (next != 0) return next; } // Either the thread wasn't found, or the range was // used up. Do the rest in a synchronized block. // The three lines tagged with the comment "*" have // the potential to collide if this wasn't synchronized. synchronized (threads) { if (gn == null) { gn = new GenNumber(next -= range); // * threads.put(current, gn); // * return gn.getNext(); // can't fail this time } // now we know the range has run out gn.setStart(next -= range); // * return gn.getNext(); } } // Instance implementation (all private, nobody needs to see this) private int start; private int count; private GenNumber(int start) { setStart(start); } private int getNext() { if (count &lt; range) return start - count; return 0; } private GenNumber setStart(int start) { this.start = start; return this; } } </code></pre> <p>It just struck me that instead of the one large synchronized block could be replaced by 2 very small ones synchronized on different objects, one for the "+= count" and one for the .put(). If collisions were still slowing you down, that might help (although if collisions were still slowing you down (REALLY???) you'd be better served just raising count.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload