4、线程范围内的数据共享之ThreadLocal
1 /** 2 * 线程范围类的数据共享 3 * 核心:ThreadLocal类 4 * 实际场景: 5 * Hibernate的getCurrentSession方法,就是从线程范围内获取存在的session,如果不存在则新建一个并绑定到线程上 6 * struts将一个请求里的所有参数绑定到一个线程范围内的对象里 7 * @author yzl 8 * 9 */ 10 public class ThreadPart_4 { 11 public static void main(String[] args) { 12 new Thread(new Runnable() { 13 public void run() { 14 MyThreadLocalObj obj = MyThreadLocalObj.getInstance(); 15 while(obj.getData()<20){ 16 obj.add(); 17 System.out.println(Thread.currentThread().getName() + " after add method value :" + obj.getData()); 18 //这里操作其实就是同一个MyThreadLocalObj对象 19 new MyAdd().add(); 20 System.out.println(Thread.currentThread().getName() + " after MyAdd add method value :" + obj.getData()); 21 try { 22 Thread.sleep(1000); 23 } catch (InterruptedException e) { 24 e.printStackTrace(); 25 } 26 } 27 } 28 }).start(); 29 30 new Thread(new Runnable() { 31 public void run() { 32 MyThreadLocalObj obj = MyThreadLocalObj.getInstance(); 33 while(obj.getData()>0){ 34 obj.sub(); 35 System.out.println(Thread.currentThread().getName() + " after sub method value :" + obj.getData()); 36 //这里操作其实就是同一个MyThreadLocalObj对象 37 new MySub().sub(); 38 System.out.println(Thread.currentThread().getName() + " after MySub sub method value :" + obj.getData()); 39 try { 40 Thread.sleep(1000); 41 } catch (InterruptedException e) { 42 e.printStackTrace(); 43 } 44 } 45 } 46 }).start(); 47 } 48 } 49 50 class MyAdd{ 51 public void add(){ 52 MyThreadLocalObj.getInstance().add(); 53 } 54 } 55 56 class MySub{ 57 public void sub(){ 58 MyThreadLocalObj.getInstance().sub(); 59 } 60 } 61 62 /** 63 * 单例模式下的 64 * 线程范围内共享 65 * 线程范围外互不影响 66 * @author yzl 67 * 68 */ 69 class MyThreadLocalObj{ 70 private int data = 10; 71 72 public void add(){ 73 data++; 74 } 75 76 public void sub(){ 77 data--; 78 } 79 80 private MyThreadLocalObj(){}; 81 private static ThreadLocal<MyThreadLocalObj> local = new ThreadLocal<MyThreadLocalObj>(); 82 83 84 public static MyThreadLocalObj getInstance(){ 85 if(local.get() == null){ 86 local.set(new MyThreadLocalObj()); 87 } 88 return local.get(); 89 } 90 91 public int getData() { 92 return data; 93 } 94 }
运行结果:
不同线程操作的对象不是同一个,同一个线程操作的是同一个
1 Thread-0 after add method value :11 2 Thread-1 after sub method value :9 3 Thread-0 after MyAdd add method value :12 4 Thread-1 after MySub sub method value :8 5 Thread-1 after sub method value :7 6 Thread-0 after add method value :13 7 Thread-1 after MySub sub method value :6 8 Thread-0 after MyAdd add method value :14 9 Thread-1 after sub method value :5 10 Thread-0 after add method value :15 11 Thread-1 after MySub sub method value :4 12 Thread-0 after MyAdd add method value :16 13 Thread-0 after add method value :17 14 Thread-1 after sub method value :3 15 Thread-0 after MyAdd add method value :18 16 Thread-1 after MySub sub method value :2 17 Thread-0 after add method value :19 18 Thread-0 after MyAdd add method value :20 19 Thread-1 after sub method value :1 20 Thread-1 after MySub sub method value :0