线程:ThreadLocal实现线程范围内共享变量
在web应用中,一个请求(带有请求参数)就是一个线程,那么如何区分哪些参数属于哪个线程呢?比如struts中,A用户登录,B用户也登录,那么在Action中怎么区分哪个是A用户的数据,哪个是B用户的数据。这就涉及到ThreadLocal类了,将变量与当前线程绑定。比如struts中,有一个容器类,那么A用户将数据放在A的容器中,B用户将数据放在B的容器中,然后再将容器与线程绑定,这样的话,A请求的线程处理A容器的数据,B请求的线程处理B容器的数据,而不会混淆。
示例如下:
1 package ch03; 2 3 import java.util.Random; 4 5 public class ThreadLocalTest { 6 7 public static void main(String[] args) { 8 Thread th = null; 9 for(int i=0; i<2; i++){ 10 th = new Thread(new Runnable() { 11 @Override 12 public void run() { 13 int data = new Random().nextInt(); 14 System.out.println(Thread.currentThread().getName()+"\t"+data); 15 Request request = Request.getThreadInstance(); 16 request.setName("name:"+data); 17 request.setAge(data); 18 19 //输出两个模块的值 20 new A().get(); 21 new B().get(); 22 } 23 }); 24 th.start(); 25 } 26 } 27 28 /*A模块*/ 29 static class A{ 30 public void get(){ 31 Request request = Request.getThreadInstance(); 32 System.out.println("A: "+Thread.currentThread().getName()+"\t"+ 33 request.getName()+"\t"+request.getAge()); 34 } 35 } 36 /*B模块*/ 37 static class B{ 38 public void get(){ 39 Request request = Request.getThreadInstance(); 40 System.out.println("B: "+Thread.currentThread().getName()+"\t"+ 41 request.getName()+"\t"+request.getAge()); 42 } 43 } 44 45 } 46 47 class Request{ 48 49 private Request(){} 50 51 /*ThreadLocal:将变量与当前线程绑定,相当于Map<Thread, value>*/ 52 private static ThreadLocal<Request> instance = new ThreadLocal<>(); 53 /*返回当前线程的单例*/ 54 public static Request getThreadInstance(){ 55 Request request = instance.get(); 56 if(request == null){ 57 request = new Request(); 58 instance.set(request); 59 } 60 return request; 61 } 62 63 private String name; 64 private int age; 65 66 public String getName() { 67 return name; 68 } 69 public void setName(String name) { 70 this.name = name; 71 } 72 public int getAge() { 73 return age; 74 } 75 public void setAge(int age) { 76 this.age = age; 77 } 78 79 }
输出结果: