Java多线程之ThreadLocal

下面是ThreadLocal的测试代码,更多信息请参考注释

  1. packagecom.jadyer.thread.local;
  2. importjava.util.Random;
  3. /**
  4. *ThreadLocalTest
  5. *@see=============================================================================================================
  6. *@seeThreadLocal的作用和目的
  7. *@seeThreadLocal用于实现线程内的数据共享。即对于相同的代码,多个模块在不同的线程中运行时,分别共享不同的数据
  8. *@see每个线程调用全局的ThreadLocal.set()方法,就相当于在其内部的Map中增加一条记录,key是各自的线程,value是各自set()传进去的值
  9. *@see=============================================================================================================
  10. *@seeThreadLocal的应用场景
  11. *@see例如Struts2中的ActionContext,同一段代码被不同的线程调用运行时,该代码操作的数据是每个线程各自的状态和数据
  12. *@see对于不同的线程来说,ActionContext.getContext()方法得到的对象都不相同
  13. *@see对于同一个线程来说,ActionContext.getContext()方法无论在哪个模块中或者是被调用多少次,其得到的都是同一个对象
  14. *@see通过查看com.opensymphony.xwork2.ActionContex的第43和166行源码,不难发现,Struts2就是这么做的
  15. *@see=============================================================================================================
  16. *@see线程中的成员变量和局部变量
  17. *@see成员变量:多个线程操作同一个对象的成员变量时,它们对成员变量的改变是彼此影响的
  18. *@see局部变量:每个线程都会有一个该局部变量的拷贝,一个线程对局部变量的改变不会影响到其它线程对该局部变量的操作
  19. *@see=============================================================================================================
  20. *@author宏宇
  21. *@createFeb27,201212:10:24AM
  22. */
  23. publicclassThreadLocalTest{
  24. publicstaticvoidmain(String[]args){
  25. newThread(newMyThread(newRandom().nextInt())).start();
  26. newThread(newMyThread(newRandom().nextInt())).start();
  27. }
  28. }
  29. classMyThreadimplementsRunnable{
  30. privateIntegerdata;
  31. publicMyThread(Integerdata){
  32. this.data=data;
  33. }
  34. @Override
  35. publicvoidrun(){
  36. System.out.println(Thread.currentThread().getName()+"hasputdata:"+data);
  37. User.getThreadInstance().setName("name"+data);
  38. User.getThreadInstance().setAge(data);
  39. newPig().getMyData();
  40. newDog().getMyData();
  41. }
  42. }
  43. classPig{
  44. publicvoidgetMyData(){
  45. Useruser=User.getThreadInstance();
  46. System.out.println("Pigfrom"+Thread.currentThread().getName()+"getMyData:"+user.getName()+"|"+user.getAge());
  47. }
  48. }
  49. classDog{
  50. publicvoidgetMyData(){
  51. Useruser=User.getThreadInstance();
  52. System.out.println("Dogfrom"+Thread.currentThread().getName()+"getMyData:"+user.getName()+"|"+user.getAge());
  53. }
  54. }
  55. /**
  56. *自定义的线程范围内共享的对象。即该类会针对不同的线程分别创建一个独立的对象
  57. *@see此时每个线程得到的将是自己的实例,各线程间得到的实例没有任何关联
  58. *@see我们可以拿它,与单例模式中的懒汉式,进行对比,这是个很有意思的东西
  59. *@seeStruts2就是这么设计的,它的每一个请求就是一个线程
  60. */
  61. classUser{
  62. privatestaticThreadLocal<User>instanceMap=newThreadLocal<User>();
  63. privateUser(){}
  64. /**
  65. *得到与当前线程相关的,当前类的实例
  66. */
  67. publicstatic/*synchronized*/UsergetThreadInstance(){
  68. Userinstance=instanceMap.get();
  69. if(null==instance){
  70. instance=newUser();
  71. instanceMap.set(instance);
  72. }
  73. returninstance;
  74. }
  75. privateStringname;
  76. privateintage;
  77. publicStringgetName(){
  78. returnname;
  79. }
  80. publicvoidsetName(Stringname){
  81. this.name=name;
  82. }
  83. publicintgetAge(){
  84. returnage;
  85. }
  86. publicvoidsetAge(intage){
  87. this.age=age;
  88. }
  89. }
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值