Previous | Next | Trail Map | Beyond the Basics | Miscellaneous

Threads and Synchronization

The JNDI defines synchronous access to naming and directory systems. Like most other APIs defined for the Java platform, asynchronous access is achieved by using multiple threads.

When you use multiple threads in your program, remember that the JNDI specifies that concurrent access to the same Context instance is not guaranteed to be thread-safe. Although some service providers might guarantee thread-safety for the same Context instance, it is best to use synchronization so that the code is portable across different service provider implementations. When you use multiple threads to access different Context instances, they need not be synchronized.

Here is an example that creates two threads, each listing a different Context instance.

// Create the contexts
Context ctx1 = new InitialContext(env);
Context ctx2 = (Context)ctx1.lookup("ou=People");

// Create the threads
Thread thread1 = new ListThread(ctx1, "ONE");
Thread thread2 = new ListThread(ctx2, "TWO");

// Let them work
thread1.start();
thread2.start();
Each thread's run() method looks as follows.
public void run() {
    try {
	NamingEnumeration enum = ctx.list("");
	while (enum.hasMore()) {
	    System.out.println(label + ": " + enum.next());
	}
    } catch (NamingException e) {
	System.out.println(label + ": " + e);
    }
}
When you run this program, you will see the following output.
# java DiffCtx
ONE: ou=Groups: javax.naming.directory.DirContext
ONE: ou=People: javax.naming.directory.DirContext
ONE: ou=Staff: javax.naming.directory.DirContext
ONE: ou=NewHires: javax.naming.directory.DirContext
TWO: cn=Ted Geisel: javax.naming.directory.DirContext
ONE: cn=favDrink: javax.naming.directory.DirContext
TWO: cn=Jon Ruiz: javax.naming.directory.DirContext
TWO: cn=Scott Seligman: javax.naming.directory.DirContext
...

Note that despite the fact that both Context instances are derived from the same InitialContext instance, you need not lock their access. However, if you modify the example slightly so that you use two threads to list the same Context, then you need to lock the Context instance. In the following modified example, the thread's run() method looks like this.

public void run() {
    try {
	// Lock for multithreaded access
	synchronized (ctx) {
	    NamingEnumeration enum = ctx.list("");
	    while (enum.hasMore()) {
		System.out.println(label + ": " + enum.next());
	    }
	}
    } catch (NamingException e) {
	System.out.println(label + ": " + e);
    }
}
When you run this example, it generates the following output.
# java SameCtx
ONE: ou=Groups: javax.naming.directory.DirContext
ONE: ou=People: javax.naming.directory.DirContext
ONE: ou=Staff: javax.naming.directory.DirContext
ONE: ou=NewHires: javax.naming.directory.DirContext
ONE: cn=favDrink: javax.naming.directory.DirContext
TWO: ou=Groups: javax.naming.directory.DirContext
TWO: ou=People: javax.naming.directory.DirContext
TWO: ou=Staff: javax.naming.directory.DirContext
TWO: ou=NewHires: javax.naming.directory.DirContext
TWO: cn=favDrink: javax.naming.directory.DirContext


Previous | Next | Trail Map | Beyond the Basics | Miscellaneous