Newsletters Subscriptions Forums Media Kit About Us Contact Search Home

mgo
OS/400 Edition
Volume 3, Number 66 -- October 1, 2003

Leveraging ThreadLocal Variables in Java


Hey, David:

Is there any way to pick up the user associated with a servlet request without passing the user as a parameter? If this were RPG, I would add a data area containing the user's name to QTEMP or use the *LDA. This seems like a basic concept, but so far I haven't seen anything like it in Java.

--Aaron


Java doesn't have a local data area, but it does have something similar with thread local variables. The class ThreadLocal allows you to associate a variable value with a thread. This is useful in a servlet because requests, which are associated with a user, are assigned to threads by the servlet container. If you place the user associated with a servlet request into a ThreadLocal variable, you can pick up and use that user downstream, without passing the user along as a parameter.

The easiest way to show how this works is with an example. The following class allows you to associate a string containing a user with a thread:

package demo;

class ThreadLocalUser {
    private static ThreadLocal name = new ThreadLocal();

    private ThreadLocalUser() {
    }

    public static String getName() {
        return (String) name.get();
    }

    public static void setName(String name) {
        ThreadLocalUser.name.set(name);
    }
}

Notice that the methods in this class are all static, which means that they can be called anywhere in your code without an instance variable. All you need to do is make a call like this:

ThreadLocalUser.setName("DAVID");

You can retrieve the user that is now associated with the thread using a call like this. It will set the name variable contained in the ThreadLocalUser class to the value "DAVID". Once the ThreadLocalUser name is set, it can be picked up by calling "get name," like this:

String user = ThreadLocalUser.getName();

To prove that this works, I created a class that will start five overlapping threads and display the user associated with the thread. I gave each thread a name that corresponded with the ThreadLocalUser, to make it easier to track the results. I ran this test with jUnit. If you don't use jUnit, you could move the code contained in testSetname to the main method of your own Java class. Here is the test code:

package demo;

import demo.ThreadLocalUser;
import junit.framework.TestCase;

public class ThreadLocalUserTest extends TestCase {
    public ThreadLocalUserTest(String arg0) {
        super(arg0);
    }

    public static void main(String[] args) {
        junit.textui.TestRunner.run(ThreadLocalUserTest.class);
    }

    public void testGetName() {
    }

    public void testSetName() {
        new Thread(new Runner(), "David").start();
        new Thread(new Runner(), "Aaron").start();
        new Thread(new Runner(), "Sam").start();
        new Thread(new Runner(), "Fred").start();
        new Thread(new Runner(), "Rufus").start();

        try {
            Thread.sleep((int) (1000));
        }
        catch (InterruptedException ignored) {
        }
    }

    class Runner
        implements Runnable {
        public void run() {
            Thread thread = Thread.currentThread();
            ThreadLocalUser.setName(thread.getName());

            for (int i = 0; i < 15; ++i) {
               System.out.println("Thread name: " + thread.getName() 
                   + " user: " + ThreadLocalUser.getName());
                assertEquals(thread.getName(), 
				   ThreadLocalUser.getName());

                try {
                    Thread.sleep(10);
                }
                catch (InterruptedException ignored) {
                }
            }
            ThreadLocalUser.setName(null);
            assertEquals(ThreadLocalUser.getName(), null);
        }
    }
}

The output of this class looks something like this:

Thread name: David user: David
Thread name: Aaron user: Aaron
Thread name: Aaron user: Aaron
Thread name: David user: David
Thread name: Sam user: Sam
Thread name: Fred user: Fred
Thread name: Rufus user: Rufus
Thread name: Rufus user: Rufus…

The most comprehensive way to take advantage of this in a servlet environment is to write a servlet filter. A servlet filter implements the javax.servlet.Filter interface and is called whenever a request is made. This allows you to intercept requests and to set your thread local user without altering existing code. Filters are relatively new to servlets, so you should check to see if your servlet container supports filters before you invest too much time in building a filter.

With filters, or in your servlet, you can use the getRemoteUser method that is provided by HttpServletRequest to retrieve the user associated with a request. So the first line of your servlet or request might look something like this:

ThreadLocalUser.setName(request.getRemoteUser());

I hope that gives you enough to get started using thread local variables, which are the *LDA of the Java world.

--David


Sponsored By
ADVANCED SYSTEMS CONCEPTS

Quoted from an experienced programmer
new to the iSeries (AS/400):

"The best thing about working on the AS/400 is using ASC's SEQUEL product."

If you're tired of the limitations imposed by Query/400 or ODBC-based query and reporting tools, you need SEQUEL. Discover how thousands of sites around the world have improved access to iSeries data using SEQUEL's Windows- and Web-interfaces. It's the one tool you can rely on for virtually all your iSeries data access needs.
FREE trial available.

Read More about SEQUEL



THIS ISSUE
SPONSORED BY:

Advanced Systems Concepts
Profound Logic Software


BACK ISSUES

TABLE OF
CONTENTS

Leveraging ThreadLocal Variables in Java

For Members Only

Reader Feedback and Insights: Unix Shell Script Is as Good as CL


Editors
Howard Arner
Joe Hertvik
Ted Holt
David Morris

Managing Editor
Shannon Pastore

Publisher and
Advertising Director:

Jenny Thomas

Advertising Sales Representative
Kim Reed

Contact the Editors
Do you have a gripe, inside dope or an opinion?
Email the editors:
editors@itjungle.com

Copyright © 1996-2008 Guild Companies, Inc. All Rights Reserved.