package Local; /** * 本例子主要是测试ThreadLocal,其实ThreadLoacl内部非常的简单,主要是内部维护一个ThreadLocalMap,为什么要自己维护一个ThreadLocalMap呢? *而使用HashMap, 因为ThreadLocalMap里面得Entry是WeakReference(弱引用)的,便于垃圾回收。 * ThreadLocal 中 的Map 以Thread.currentThread 为key * * @author Administrator * */ public class ThreadLocalTest { public static void main(String[] args) { // 模拟HttpServlent 单例 UserServlet servlent = new UserServlet(); // 模拟10线程登录,访问HttpServlent for (int i = 0; i < 10; i++) { new UserLoginThread(servlent, new User("User " + i)).start(); } } } /** * 模拟一个线程登录 * @author Administrator * */ class UserLoginThread extends Thread { UserServlet userServlent; User user; public UserLoginThread(UserServlet userServlent, User user) { super(); this.userServlent = userServlent; this.user = user; } public void run() { super.run(); userServlent.doPost(user); } } /** * 模拟HttpServlent 登录 * * @author Administrator * */ class UserServlet { MyService service = new MyService(); public void doPost(User user) { UserContext.login(user); work(); } public void work() { /** * 这里可能调用其他的Service,Service类里面只要没有开其他线程,那么如果要使用当前登录的User都可以使用UserContext * .getUser() 方法来获取User,好处是不需要处处传递User */ service.printlnUser(); } } class MyService { public void printlnUser() { System.out.println(Thread.currentThread().getName() + " " + UserContext.getUser().getName()); } } /** * User上下文 * * @author Administrator * */ class UserContext { static ThreadLocal<User> context = new ThreadLocal<User>(); public static void login(User user) { context.set(user); } public static User getUser() { return context.get(); } } /** * 用户 * * @author Administrator * */ class User { private String name; public User(String name) { super(); this.name = name; } public String getName() { return name; } public void setName(String name) { this.name = name; } }