Re: Using Enumerated Types as Array Indexes
On 18.08.2011 03:50, Eric Sosman wrote:
On 8/17/2011 7:09 PM, markspace wrote:
On 8/17/2011 10:02 AM, Robert Klemme wrote:
1. There was an AtomicInteger initialized at startup with 0 which for
every request coming into that system was incremented in a thread safe
manner (incrementAndGet()).
I'd be shocked if an int actually overflowed when counting requests like
this, but that's all I can think of. 2^31 is such a huge number, I
didn't think you could get there in practical cases.
He *did* write "two months of uninterrupted [...] usage." Two
months ~= 60 days ~= 5 megaseconds, so a 2G counter overflows if it
increments at ~400 Hz or more, give or take a few backs of envelopes.
Exactly. A good example where it pays off to do the basic math instead
of relying on gut feelings. :-)
Assuming that the AtomicInteger did overflow, then n % y produces
negative numbers if n is negative, a clear AIOOB.
Try : arr[ Math.abs( n ) % arr.length ];
Bzzzzt! Thank you for playing, go back to the rear of the line.
While awaiting your next opportunity, ponder: What is the sign of
Math.abs(Integer.MIN_VALUE)?
All solutions to fix remainder into modulo but keep the wrap around
which have been proposed so far share a common disadvantage: if the
number range is not a multiple of the divisor the value distribution
will not be uniform. Example:
number range: [0,3]
divisor: 3
value sequence:
0 : 0
1 : 1
2 : 2
3 : 0
wrap to 0
0: 50%
1: 25%
2: 25%
Now with Integer.MAX_VALUE and realistic values for the divisor which
are usually much smaller than Integer.MAX_VALUE the effects are not so
dramatic but the repetition of a single value (0 in the example) might
cause trouble for a round robin scheme - even if only once every two
months (in other installations that would mean once every two weeks or
even shorter).
The solution I used to fix this employed a do while loop and
compareAndSet() to reset the value to the beginning of the range (0 in
this case) in a thread safe manner.
http://download.oracle.com/javase/6/docs/api/java/util/concurrent/atomic/AtomicInteger.html#compareAndSet%28int,%20int%29
Kind regards
robert
--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/