package com.thread.threadlocal; import java.util.Random; /** * http://www.linuxidc.com/Linux/2012-03/57070.htm * * ThreadLocal Test * @see ============================================================================================================= * @see ThreadLocal的做用和目的 * @see ThreadLocal用於實現線程內的數據共享。即對於相同的代碼,多個模塊在不一樣的線程中運行時,分別共享不一樣的數據 * @see 每一個線程調用全局的ThreadLocal.set()方法,就至關於在其內部的Map中增長一條記錄,key是各自的線程,value是各自set()傳進去的值 * @see ============================================================================================================= * @see ThreadLocal的應用場景 * @see 例如Struts2中的ActionContext,同一段代碼被不一樣的線程調用運行時,該代碼操做的數據是每一個線程各自的狀態和數據 * @see 對於不一樣的線程來講,ActionContext.getContext()方法獲得的對象都不相同 * @see 對於同一個線程來講,ActionContext.getContext()方法不管在哪一個模塊中或者是被調用多少次,其獲得的都是同一個對象 * @see 經過查看com.opensymphony.xwork2.ActionContex的第43和166行源碼,不難發現,Struts2就是這麼作的 * @see ============================================================================================================= * @see 線程中的成員變量和局部變量 * @see 成員變量:多個線程操做同一個對象的成員變量時,它們對成員變量的改變是彼此影響的 * @see 局部變量:每一個線程都會有一個該局部變量的拷貝,一個線程對局部變量的改變不會影響到其它線程對該局部變量的操做 * @see ============================================================================================================= */ public class ThreadLocalTest { public static void main(String[] args) { new Thread(new MyThread(new Random().nextInt())).start(); new Thread(new MyThread(new Random().nextInt())).start(); } } class MyThread implements Runnable{ private Integer data; public MyThread(Integer data){ this.data = data; } @Override public void run() { System.out.println(Thread.currentThread().getName() + " has put data:" + data); User.getThreadInstance().setName("name" + data); User.getThreadInstance().setAge(data); new Pig().getMyData(); new Dog().getMyData(); } } class Pig{ public void getMyData(){ User user = User.getThreadInstance(); System.out.println("Pig from " + Thread.currentThread().getName() + " getMyData:" + user.getName() + "|" + user.getAge()); } } class Dog{ public void getMyData(){ User user = User.getThreadInstance(); System.out.println("Dog from " + Thread.currentThread().getName() + " getMyData:" + user.getName() + "|" + user.getAge()); } } class User{ private static ThreadLocal<User> instanceMap = new ThreadLocal<User>(); private User(){} /** * 獲得與當前線程相關的,當前類的實例 */ public static /*synchronized*/ User getThreadInstance(){ User instance = instanceMap.get(); if(null == instance){ instance = new User(); instanceMap.set(instance); } return instance; } private String name; private int age; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } }