ITeedu.com
自由计划
我的网盘
关于
快捷导航
编程语言
WEB开发
手机开发
数据库
操作系统
嵌入式
开源软件
作品
编辑语言
汇编
C/C++
JAVA
Python
Ruby
WEB开发
javascript
J2EE
PHP
Django
ITEEDU
首页
编程语言
汇编
C&C++
JAVA
Python
JAVA笔记主页
JAVA线程安全首页
JAVA同步基础
JAVA同步之线程状态
JAVA同步之守护线程和JOIN方法
JAVA同步之wait()和notify()的使用
JAVA同步之synchronized关键字的使用
JAVA同步设计败笔synchronized
JAVA同步之线程缓存与volatile关键字
JAVA同步之Atomic类的使用
JAVA同步之ThreadLocal的使用
JAVA同步之ThreadLocal使用示例
JAVA同步锁
JAVA同步之ReentrantLock 类简介
JAVA同步之ReentrantLock多条件的使用
JAVA同步之ReentrantLock可中断锁的使用
JAVA同步之ReentrantReadWriteLock
线程安全容器
JAVA同步之线程安全队列Queue
JAVA同步之ArrayBlockingQueue
JAVA同步之LinkedBlockingQueue
LinkedBlockingQueue生产消费模型简单实现
JAVA同步之ConcurrentLinkedQueue
线程池
JAVA同步之线程池简介
JAVA线程池submit和Future的使用
其它
JAVA实现生产者/消费者问题的多种方式
JAVA同步之ThreadLocal的使用
当多个线程可以访问一个对象的实例变量时,这个实例变量是线程不安全的。如果我们想保证变量的原子性可以用Synchonized来解决。如果我们想让每个线程都有自己的实例变量怎么办? 比如一个Servlet中众多方法要使用数据库的查询内容,但每个请求的查询内容是不同的,这就要求方法在获取数据库查询内容时是指定线程查出来的。这时就要用到ThreadLocal。 ThreadLocal的实现原理很简单,每个Thread都有一个MAP,叫做threadLocals。 public class Thread implements Runnable { ... ThreadLocal.ThreadLocalMap threadLocals = null; ... } ThreadLocal主要用两个方法: void set(Object obj) 设置当前线程的变量的副本的值。 Object get() 返回当前线程的变量副本 看一下具体实现: public T get() { Thread t = Thread.currentThread(); ThreadLocalMap map = getMap(t); if (map != null) { ThreadLocalMap.Entry e = map.getEntry(this); if (e != null) return (T)e.value; } return setInitialValue(); } public void set(T value) { Thread t = Thread.currentThread(); ThreadLocalMap map = getMap(t); if (map != null) map.set(this, value); else createMap(t, value); } 它设置的是当前线程中的threadLocals这个MAP,Map的key是ThreadLocal对象本身的实例。 来一个例子: public class ThreadLocalDemo implements Runnable { private final static ThreadLocal studentLocal = new ThreadLocal(); //ThreadLocal对象在这 public static void main(String[] agrs) { TreadLocalDemo td = new TreadLocalDemo(); Thread t1 = new Thread(td,"a"); Thread t2 = new Thread(td,"b"); t1.start(); t2.start(); } public void run() { accessStudent(); } public void accessStudent() { String currentThreadName = Thread.currentThread().getName(); System.out.println(currentThreadName+" is running!"); Random random = new Random(); int age = random.nextInt(100); System.out.println("thread "+currentThreadName +" set age to:"+age); Student student = getStudent(); //每个线程都独立维护一个Student变量 student.setAge(age); System.out.println("thread "+currentThreadName+" first read age is:"+student.getAge()); try { Thread.sleep(5000); } catch(InterruptedException ex) { ex.printStackTrace(); } System.out.println("thread "+currentThreadName +" second read age is:"+student.getAge()); } protected Student getStudent() { Student student = (Student)studentLocal.get(); //从ThreadLocal对象中取 if(student == null) { student = new Student(); studentLocal.set(student); //如果没有就创建一个 } return student; } protected void setStudent(Student student) { studentLocal.set(student); //放入ThreadLocal对象中 } }