Download the entire Java Getting Started Source code and follow along with the steps.
You can compile and run the program using the following steps.
shell> javac -cp couchbase-client-1.0.0.jar:spymemcached-2.8.0.jar \ GettingStarted.java shell> java -cp .:couchbase-client-1.0.0.jar:\ spymemcached-2.8.0.jar:jettison-1.1.jar:netty-3.2.0.Final.jar:\ commons-codec-1.5.jar GettingStarted http://192.168.3.104:8091/pools 10
Running this program generates the following output the first time:
Client-2 took 37.2500 ms per key. Created 35. Retrieved 65 from cache. Client-3 took 37.7800 ms per key. Created 35. Retrieved 65 from cache. Client-4 took 37.7100 ms per key. Created 35. Retrieved 65 from cache. Client-0 took 37.8300 ms per key. Created 35. Retrieved 65 from cache. Client-1 took 37.8400 ms per key. Created 35. Retrieved 65 from cache.
Running the program a second time before 15 seconds elapses, produces this output instead:
Client-1 took 4.6700 ms per key. Created 0. Retrieved 100 from cache. Client-3 took 4.6000 ms per key. Created 0. Retrieved 100 from cache. Client-4 took 4.7500 ms per key. Created 0. Retrieved 100 from cache. Client-2 took 4.7900 ms per key. Created 0. Retrieved 100 from cache. Client-0 took 4.8400 ms per key. Created 0. Retrieved 100 from cache.
There are a few things that are interesting about the output. In the first scenario, the five threads collaborate to produce the sequence of random numbers such that the average time per key is significantly less than 100ms. Each thread is creating 35 numbers, but reading 65 from the cache.
In the second run, because the 15 second timeout has not elapsed yet, all of the random numbers were retrieved from the cache by all of the threads. Notice that reading these values from Couchbase only takes a few milliseconds.
The complete source code for this is below. You would run this with the command line arguments like below after ensuring that the client libraries are included in the classpath.
shell> javac -cp couchbase-client-1.0.0.jar:spymemcached-2.8.0.jar \ GettingStarted.java shell> java -cp .:couchbase-client-1.0.0.jar:\ spymemcached-2.8.0.jar:jettison-1.1.jar:netty-3.2.0.Final.jar:\ commons-codec-1.5.jar GettingStarted http://192.168.3.104:8091/pools 10
import java.util.Random; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; import java.util.ArrayList; import java.net.URI; import com.couchbase.client.CouchbaseClient; import net.spy.memcached.CASValue; import net.spy.memcached.transcoders.IntegerTranscoder; /** * Sets up a number of threads each cooperating to generate a set of random * numbers and illustrates the time savings that can be achieved by using * Couchbase. */ public class GettingStarted { static final int numIntegers = 100; static String addresses; static CountDownLatch countdown; /** * @param args */ public static void main(String[] args) { if (args.length < 2) { System.err.println("usage: addresses numthreads"); System.exit(1); } addresses = args[0]; int numThreads = Integer.parseInt(args[1]); countdown = new CountDownLatch(numThreads); for (int i = 0; i < numThreads; i++) { Thread t = new Thread(new ClientThread(String.format( "Client-%d", i))); t.setName("Client Thread " + i); t.start(); } try { countdown.await(); } catch (InterruptedException e) { } System.exit(0); } private static class ClientThread implements Runnable { private String name; public ClientThread(String name) { this.name = name; } @Override public void run() { try { URI server = new URI(addresses); ArrayList<URI> serverList = new ArrayList<URI>(); serverList.add(server); CouchbaseClient client = new CouchbaseClient( serverList, "default", ""); IntegerTranscoder intTranscoder = new IntegerTranscoder(); // Not really random, all threads // will have the same seed and sequence of // numbers. Random rand = new Random(1); long startTime = System.currentTimeMillis(); int created = 0; int cached = 0; for (int i = 0; i < numIntegers; i++) { String key = String.format("Value-%d", i); CASValue<Integer> value = client.gets(key, intTranscoder); if (value == null) { // The value doesn't exist in Membase client.set(key, 15, rand.nextInt(), intTranscoder); // Simulate the value taking time to create. Thread.sleep(100); created++; } else { // The value does exist, another thread // created it already so this thread doesn't // have to. int v = value.getValue(); // Check that the value is what we // expect it to be. if (v != rand.nextInt()) { System.err.println("No match."); } cached++; } client.waitForQueues(1, TimeUnit.MINUTES); } System.err.println(String.format( "%s took %.4f ms per key. Created %d." + " Retrieved %d from cache.", name, (System.currentTimeMillis() - startTime) / (double)numIntegers, created, cached)); } catch (Throwable ex) { ex.printStackTrace(); } countdown.countDown(); } } }