RateExceedDetector { public boolean updateAndCheckRate() { final long nowTimeMicros = TimeUnit.NANOSECONDS.toMicros(System.nanoTime()); final boolean exceed = (nowTimeMicros - threshold) < 0; threshold = nowTimeMicros + intervalMicros; countRate(nowTimeMicros); return exceed; } RateExceedDetector(double permits); boolean updateAndCheckRate(); double getRate();  }
@Test public void testExceedRate() throws Exception { RateExceedDetector rd = new RateExceedDetector(1); Assert.assertFalse(rd.updateAndCheckRate()); Thread.sleep(500); Assert.assertTrue(rd.updateAndCheckRate()); }
@Test public void testStayUnderLimit() throws Exception { RateExceedDetector rd = new RateExceedDetector(3); Assert.assertFalse(rd.updateAndCheckRate()); Thread.sleep(400); Assert.assertFalse(rd.updateAndCheckRate()); }
@Test public void testComplex() throws Exception { RateExceedDetector rd = new RateExceedDetector(3); Assert.assertFalse(rd.updateAndCheckRate()); Thread.sleep(200); Assert.assertTrue(rd.updateAndCheckRate()); Thread.sleep(500); Assert.assertFalse(rd.updateAndCheckRate()); }