Recently, I needed to do a quick, non-competitive evaluation of the performance of Couchbase (around 3,500 inserts / second) and Apache Geode (around 8,100 inserts / second.) The simple pattern shown below was very useful and shows off some of the Java 8 goodness. Of course, for "proper" performance, stress or load testing use Gatling and/or JMeter on a server with the desired networking (likely not over VPN on a laptop as mine was.) For those new to Java 8, I’ve found this very useful http://winterbe.com/posts/2014/03/16/java-8-tutorial

@Test
public void testLoad() throws InterruptedException {
    // load() is reusable; so this "test" is just passing the runnable, thread count and timeout
    load(insertUserRunnable(1000), 1024, 480);
}

private void load(Runnable runnable, int threadCount, long timeoutSeconds) throws InterruptedException {
    ExecutorService executor = Executors.newFixedThreadPool(threadCount);
    IntStream.range(0, threadCount).forEach(i -> executor.submit(runnable));
    executor.shutdown();
    executor.awaitTermination(timeoutSeconds, TimeUnit.SECONDS);
}

private Runnable insertUserRunnable(int count) {
    return () -> IntStream.range(0, count).forEach(i -> insertUser());
}

private User insertUser() {
    return region.put(UUID.randomUUID().toString(), buildUser());
}

private User buildUser() {
    return User.builder().email("abc").firstName("xyz").build().role("XX").role("YY");
}

I especially like how the type of the Runnable is automatically inferred in the insertUserRunnable() method and how easy the newFixedThreadPool() syntax in the load() method makes worker creation. Keen eyes may note the usage of Lombok @Builder on the last line. Of course, IntStream.range() has been a long time coming…​ Maybe Range, Regex and Map literals will be here soon! (But I’m not holding my breath :-)

For more information, take a look at https://en.wikipedia.org/wiki/Java_concurrency and "Java Concurrency in Practice" by Goetz and Bloch.