ThreadLocal
Thread-->人类
Runnable-->任务类
多线程并发问题引出ThreadLocal
多线程并发问题的原因:
操作同一个对象,对对象具有读写权限(只读如拍照,不会改变什么),几乎或者同时操作
解决这个问题的常规方式:
同步锁,synchronized代码块。
我们知道,使用同步锁的时候,程序运行到这个地方就需要等待,成为一个串。十分影响效率。专业人士测试过,效率慢了100多倍
那么如何解决并发问题呢?
我们将并发问题的原因分离出来。有些操作是必须并发的,有些操作是因为资源的位置等原因出现并发问题的。只要不会修改原来数据的内容,我们为什么不可以给它一个映像呢?
当然,绝对的并发就必须牺牲效率。
ThreadLocal是什么?
ThreadLocal是一个容器。它有三个方法:
void set(T value):保存值
T get():获取值
void remove():移除值
ThreadLocal内部其实是一个Map集合。虽然在使用ThreadLocal的时候只使用了值没有给出键,其实它内部使用了当前线程作为键
Map map=new HashMap<Thread,T>
package cn.itcast.thread; import java.util.HashMap; import java.util.Map; import org.junit.Test; public class Demo1 { @Test public void fun1(){ final ThreadLocal<String> t1=new ThreadLocal<String>(); t1.set("hello"); System.out.println(t1.get()); t1.remove(); System.out.println(t1.get()); } @Test public void fun2(){ final ThreadLocal<String> t1=new ThreadLocal<String>(); new Thread(){ public void run(){ t1.set("内部类"); System.out.println(t1.get()); } }.start(); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(t1.get()); } @Test public void fun3(){ final Map<Thread,String> map=new HashMap<Thread,String>(); map.put(Thread.currentThread(), "hello"); System.out.println(map.get(Thread.currentThread())); new Thread(){ public void run(){ System.out.println(Thread.currentThread().getName()); System.out.println(map.get(Thread.currentThread())); } }.start(); } } /** * 它内部是一个Map */ class TL<T>{ private Map<Thread,T> map=new HashMap<Thread,T>(); public void set(T data){ map.put(Thread.currentThread(),data); } public T get(){ return map.get(Thread.currentThread()); } public void remove(){ map.remove(Thread.currentThread()); } } /** * ThreadLocal通常用在一个类的成员上 * 多个线程访问它时,每个线程都有自己的副本,互不干扰 * Hibernate中把Session放到了ThreadLocal中! */ class User{ private ThreadLocal<String> usernameT1=new ThreadLocal<String>(); }