Path: csiph.com!x330-a1.tempe.blueboxinc.net!newsfeed.hal-mli.net!feeder1.hal-mli.net!feeder.news-service.com!newsfeed.kamp.net!newsfeed.kamp.net!fu-berlin.de!uni-berlin.de!individual.net!not-for-mail From: Robert Klemme Newsgroups: comp.lang.java.programmer Subject: Re: Using Enumerated Types as Array Indexes Date: Fri, 19 Aug 2011 14:13:18 +0200 Lines: 67 Message-ID: <9b72b5FrgfU1@mid.individual.net> References: <4e4b0d81$0$314$14726298@news.sunsite.dk> <4e4b1fe4$0$314$14726298@news.sunsite.dk> <6d418cda-dab3-43df-a9ec-293b43f2bbd8@glegroupsg2000goo.googlegroups.com> <9b2aglFuj7U1@mid.individual.net> Mime-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit X-Trace: individual.net oMltx+QKPT/KDsjg37QuUgn8KjwqZneUvDHbQ/9XZEZ9rWLvE= Cancel-Lock: sha1:EA4CbIh9c+zjHvhzCnbXay6cE8o= User-Agent: Mozilla/5.0 (Windows NT 6.0; WOW64; rv:6.0) Gecko/20110812 Thunderbird/6.0 In-Reply-To: Xref: x330-a1.tempe.blueboxinc.net comp.lang.java.programmer:7249 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/