HystrixRollingPercentile { public void addValue(int... value) { if (!enabled.get()) return; for (int v : value) { try { getCurrentBucket().data.addValue(v); } catch (Exception e) { logger.error("Failed to add value: " + v, e); } } } @Deprecated  HystrixRollingPercentile(HystrixProperty<Integer> timeInMilliseconds, HystrixProperty<Integer> numberOfBuckets, HystrixProperty<Integer> bucketDataLength, HystrixProperty<Boolean> enabled);  HystrixRollingPercentile(int timeInMilliseconds, int numberOfBuckets, int bucketDataLength, HystrixProperty<Boolean> enabled);   HystrixRollingPercentile(Time time, int timeInMilliseconds, int numberOfBuckets, int bucketDataLength, HystrixProperty<Boolean> enabled); void addValue(int... value); int getPercentile(double percentile); int getMean(); void reset();  }
@Test public void testWriteThreadSafety() { final MockedTime time = new MockedTime(); final HystrixRollingPercentile p = new HystrixRollingPercentile(time, 100, 25, 1000, HystrixProperty.Factory.asProperty(true)); final int NUM_THREADS = 10; final int NUM_ITERATIONS = 1000; final CountDownLatch latch = new CountDownLatch(NUM_THREADS); final Random r = new Random(); final AtomicInteger added = new AtomicInteger(0); for (int i = 0; i < NUM_THREADS; i++) { threadPool.submit(new Runnable() { @Override public void run() { for (int j = 1; j < NUM_ITERATIONS / NUM_THREADS + 1; j++) { int nextInt = r.nextInt(100); p.addValue(nextInt); added.getAndIncrement(); } latch.countDown(); } }); } try { latch.await(100, TimeUnit.SECONDS); assertEquals(added.get(), p.buckets.peekLast().data.length()); } catch (InterruptedException ex) { fail("Timeout on all threads writing percentiles"); } }