知识大全 深入ThreadLocal

Posted 变量

篇首语:我们要像海绵一样吸收有用的知识。本文由小常识网(cha138.com)小编为大家整理,主要介绍了知识大全 深入ThreadLocal相关的知识,希望对你有一定的参考价值。

Java线程:深入ThreadLocal  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!

  ThreadLocal与线程成员变量还有区别 ThreadLocal该类提供了线程局部变量 这个局部变量与一般的成员变量不一样 ThreadLocal的变量在被多个线程使用时候 每个线程只能拿到该变量的一个副本 这是Java API中的描述 通过阅读API源码 发现并非副本 副本什么概念?克隆品? 或者是别的样子 太模糊

  准确的说 应该是ThreadLocal类型的变量内部的注册表(Map<Thread T>)发生了变化 但ThreadLocal类型的变量本身的确是一个 这才是本质!

  下面就做个例子

  一 标准例子

  定义了MyThreadLocal类 创建它的一个对象tlt 分别给四个线程使用 结果四个线程tlt变量并没有出现共用现象 二是各用各的 这说明 四个线程使用的是tlt的副本(克隆品)

  /**

  * 使用了ThreadLocal的类

  *

  * @author leizhimin : :

  */

  public class MyThreadLocal

  //定义了一个ThreadLocal变量 用来保存int或Integer数据

  private ThreadLocal<Integer> tl = new ThreadLocal<Integer>()

  @Override

  protected Integer initialValue()

  return ;

  

  ;

  public Integer getNextNum()

  //将tl的值获取后加 并更新设置t 的值

  tl set(tl get() + );

  return tl get();

  

  

  /**

  * 测试线程

  *

  * @author leizhimin : :

  */

  public class TestThread extends Thread

  private MyThreadLocal tlt = new MyThreadLocal();

  public TestThread(MyThreadLocal tlt)

  this tlt = tlt;

  

  @Override

  public void run()

  for (int i = ; i < ; i++)

  System out println(Thread currentThread() getName() + \\t + tlt getNextNum());

  

  

  

  /**

  * ThreadLocal测试

  *

  * @author leizhimin : :

  */

  public class Test

  public static void main(String[] args)

  MyThreadLocal tlt = new MyThreadLocal();

  Thread t = new TestThread(tlt);

  Thread t = new TestThread(tlt);

  Thread t = new TestThread(tlt);

  Thread t = new TestThread(tlt);

  t start();

  t start();

  t start();

  t start();

  

  

  可以看出 三个线程各自独立编号 互不影响

  Thread  

  Thread  

  Thread  

  Thread  

  Thread  

  Thread  

  Thread  

  Thread  

  Thread  

  Thread  

  Thread  

  Thread  

  Process finished with exit code

  tlt对象是一个 废话tl对象也是一个 因为组合关系是一对一的 但是tl对象内部的Map随着线程的增多 会创建很多Integer对象 只是Integer和int已经通用了 所以感觉不到Integer的对象属性

  二 不用ThreadLocal

  假如不用ThreadLocal 只需要将MyThreadLocal类重新定义为

  /**

  * 使用了ThreadLocal的类

  *

  * @author leizhimin : :

  */

  public class MyThreadLocal

  private Integer t = ;

  public Integer getNextNum()

  return t =t + ;

  

  //        //定义了一个ThreadLocal变量 用来保存int或Integer数据

  //        private ThreadLocal<Integer> tl = new ThreadLocal<Integer>()

  //                @Override

  //                protected Integer initialValue()

  //                        return ;

  //               

  //        ;

  //

  //        public Integer getNextNum()

  //                //将tl的值获取后加 并更新设置t 的值

  //                tl set(tl get() + );

  //                return tl get();

  //       

  

  然后运行测试

  Thread  

  Thread  

  Thread  

  Thread  

  Thread  

  Thread  

  Thread  

  Thread  

  Thread  

  Thread  

  Thread  

  Thread  

  Process finished with exit code

  从这里可以看出 四个线程共享了tlt变量 结果每个线程都直接修改tlt的属性

  三 自己实现个ThreadLocal

  package lavasoft test ;

  import java util Collections;

  import java util HashMap;

  import java util Map;

  /**

  * 使用了ThreadLocal的类

  *

  * @author leizhimin : :

  */

  public class MyThreadLocal

  //定义了一个ThreadLocal变量 用来保存int或Integer数据

  private lavasoft test ThreadLocal<Integer> tl = new lavasoft test ThreadLocal<Integer>()

  @Override

  protected Integer initialValue()

  return ;

  

  ;

  public Integer getNextNum()

  //将tl的值获取后加 并更新设置t 的值

  tl set(tl get() + );

  return tl get();

  

  

  class ThreadLocal<T>

  private Map<Thread T> map = Collections synchronizedMap(new HashMap<Thread T>());

  public ThreadLocal()

  

  protected T initialValue()

  return null;

  

  public T get()

  Thread t = Thread currentThread();

  T obj = map get(t);

  if (obj == null && !ntainsKey(t))

  obj = initialValue();

  map put(t obj);

  

  return obj;

  

  public void set(T value)

  map put(Thread currentThread() value);

  

  public void remove()

  map remove(Thread currentThread());

  

  

  运行测试

  Thread  

  Thread  

  Thread  

  Thread  

  Thread  

  Thread  

  Thread  

  Thread  

  Thread  

  Thread  

  Thread  

  Thread  

  Process finished with exit code

  很意外 这个山寨版的ThreadLocal也同样运行很好 实现了JavaAPI中ThreadLocal的功能

  四 透过现象看本质

  其实从程序角度看 tlt变量的确是一个 毫无疑问的 但是为什么打印出来的数字就互不影响呢?

  是因为使用了Integer吗? 不是

  原因是 protected T initialValue()和get() 因为每个线程在调用get()时候 发现Map中不存在就创建 调用它的时候 就创建了一个新变量 类型为T 每次都新建 当然各用个的互不影响了

  为了看清本质 将Integer换掉 重写部分类

  package lavasoft test ;

  import java util Collections;

  import java util HashMap;

  import java util Map;

  /**

  * 使用了ThreadLocal的类

  *

  * @author leizhimin : :

  */

  public class MyThreadLocal

  //定义了一个ThreadLocal变量 用来保存int或Integer数据

  //        private ThreadLocal<Bean> tl = new ThreadLocal<Bean>()

  private lavasoft test ThreadLocal<Bean> tl = new lavasoft test ThreadLocal<Bean>()

  @Override

  protected Bean initialValue()

  return new Bean();

  

  ;

  @Override

  public String toString()

  return MyThreadLocal +

   tl= + tl +

   ;

  

  public Bean getBean()

  return tl get();

  

  

  class ThreadLocal<T>

  private Map<Thread T> map = Collections synchronizedMap(new HashMap<Thread T>());

  public ThreadLocal()

  

  protected T initialValue()

  return null;

  

  public T get()

  Thread t = Thread currentThread();

  T obj = map get(t);

  if (obj == null && !ntainsKey(t))

  obj = initialValue();

  map put(t obj);

  

  return obj;

  

  public void set(T value)

  map put(Thread currentThread() value);

  

  public void remove()

  map remove(Thread currentThread());

  

  

  package lavasoft test ;

  /**

  * 测试Bean

  *

  * @author leizhimin : :

  */

  public class Bean

  private String id = ;

  private String name = none ;

  public Bean()

  

  public Bean(String id String name)

  this id = id;

  this name = name;

  

  public String getId()

  return id;

  

  public void setId(String id)

  this id = id;

  

  public String getName()

  return name;

  

  public void setName(String name)

  this name = name;

  

  public String showinfo()

  return Bean +

   id= + id + \\ +

   name= + name + \\ +

   ;

  

  

  package lavasoft test ;

  /**

  * 测试线程

  *

  * @author leizhimin : :

  */

  public class TestThread extends Thread

  private MyThreadLocal tlt = new MyThreadLocal();

  public TestThread(MyThreadLocal tlt)

  this tlt = tlt;

  

  @Override

  public void run()

  System out println( >>>>>: + tlt);

  for (int i = ; i < ; i++)

  System out println(Thread currentThread() getName() + \\t +tlt getBean()+ \\t +tlt getBean() showinfo());

  

  

  

  然后运行测试

  >>>>>:MyThreadLocaltl= lavasoft test MyThreadLocal$ @ de f d

  >>>>>:MyThreadLocaltl= lavasoft test MyThreadLocal$ @ de f d

  >>>>>:MyThreadLocaltl= lavasoft test MyThreadLocal$ @ de f d

  >>>>>:MyThreadLocaltl= lavasoft test MyThreadLocal$ @ de f d

  Thread   lavasoft test Bean@ aff  Beanid= name= none

  Thread   lavasoft test Bean@fe b   Beanid= name= none

  Thread   lavasoft test Bean@ db   Beanid= name= none

  Thread   lavasoft test Bean@fe b   Beanid= name= none

  Thread   lavasoft test Bean@fe b   Beanid= name= none

  Thread   lavasoft test Bean@ aff  Beanid= name= none

  Thread   lavasoft test Bean@ db   Beanid= name= none

  Thread   lavasoft test Bean@ db   Beanid= name= none

  Thread   lavasoft test Bean@ aff  Beanid= name= none

  Thread   lavasoft test Bean@ aff  Beanid= name= none

  Thread   lavasoft test Bean@ aff  Beanid= name= none

  Thread   lavasoft test Bean@ aff  Beanid= name= none

  Process finished with exit code

cha138/Article/program/Java/gj/201311/27562

相关参考

知识大全 Java并发编程实践之ThreadLocal变量

Java并发编程实践之ThreadLocal变量  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  

知识大全 深入解剖 LILO

深入解剖LILO  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  本文我们将深入底层来讲述LILO

知识大全 深入RAP

EclipseGanymede:深入RAP  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  作为即

知识大全 深入浅出Hibernate的属性查询

深入浅出Hibernate的属性查询  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  《深入浅出H

麦克连指标深入讲解

麦克连指标深入讲解顺势操作依剑法1、2的说明,读者了解MCL是一种超买超卖指标,市场处于“常态行情”时,股民采用“低买高卖”策略,似乎相当合理。但是,众所皆知,行情的波动不可能如此理想化,市场经常出现

知识大全 深入了解String

深入了解String  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!一从根本上认识javalangS

知识大全 深入解析contentWindow, contentDocument

深入解析contentWindow,contentDocument  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一

知识大全 数据绑定深入理解[3]

C#高级编程:数据绑定深入理解[3]  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! &n

知识大全 数据绑定深入理解[4]

C#高级编程:数据绑定深入理解[4]  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! &n

知识大全 数据绑定深入理解[1]

C#高级编程:数据绑定深入理解[1]  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! &n