java threadlocal 例子_Java ThreadLocal示例及使用方法总结

一、概述

ThreadLocal的名称比较容易让人误解,会认为其是一个“本地线程”。其实,ThreadLocal并不是一个Thread,而是Thread的局部变量。

其设计的初衷是为了解决多线程编程中的资源共享问题。提起这个,大家一般会想到synchronized,synchronized采取的是“以时间换空间”的策略,本质上是对关键资源上锁,让大家排队操作。而ThreadLocal采取的是“以空间换时间”的思路,为每个使用该变量的线程提供独立的变量副本,在本线程内部,它相当于一个“全局变量”,可以保证本线程任何时间操纵的都是同一个对象。

二、实例

下面用一个实例阐述ThreadLocal的使用方法

创建一个Context类,其中含有transactionId属性。

48304ba5e6f9fe08f3fa1abda7d326ab.png

1 package com.vigar;

2

3 public class Context {

4

5 private String transactionId = null;

6

7 public String getTransactionId() {

8 return transactionId;

9 }

10

11 public void setTransactionId(String transactionId) {

12 this.transactionId = transactionId;

13 }

14 }

48304ba5e6f9fe08f3fa1abda7d326ab.png

创建MyThreadLocal做为容器,将一个Context对象保存于ThreadLocal中

48304ba5e6f9fe08f3fa1abda7d326ab.png

1 package com.vigar;

2

3 public class MyThreadLocal {

4 public static final ThreadLocal userThreadLocal = new ThreadLocal();

5 public static void set(Context user) {

6 userThreadLocal.set(user);

7 }

8

9 public static void unset() {

10 userThreadLocal.remove();

11 }

12

13 public static Context get() {

14 return (Context)userThreadLocal.get();

15 }

16 }

48304ba5e6f9fe08f3fa1abda7d326ab.png

多线程客户端程序,用于测试

48304ba5e6f9fe08f3fa1abda7d326ab.png

1 package com.vigar;

2

3 import java.util.Random;

4

5 public class ThreadLocalDemo extends Thread {

6

7 public static void main(String[] args) {

8 Thread threadOne = new ThreadLocalDemo();

9 threadOne.start();

10 Thread threadTwo = new ThreadLocalDemo();

11 threadTwo.start();

12 }

13

14 @Override

15 public void run() {

16 // 线程

17 Context context = new Context();

18 Random random = new Random();

19 int age = random.nextInt(100);

20 context.setTransactionId(String.valueOf(age));

21

22 System.out.println("set thread ["+getName()+"] contextid to " + String.valueOf(age));

23 // 在ThreadLocal中设置context

24 MyThreadLocal.set(context);

25 /* note that we are not explicitly passing the transaction id */

26 try {

27 Thread.sleep(1000);

28 } catch (InterruptedException e)

29 {

30 e.printStackTrace();

31 }

32

33 new BusinessService().businessMethod();

34 MyThreadLocal.unset();

35 }

36 }

48304ba5e6f9fe08f3fa1abda7d326ab.png

模拟业务层,在某处读取context对象

48304ba5e6f9fe08f3fa1abda7d326ab.png

1 package com.vigar;

2 public class BusinessService {

3 public void businessMethod() {

4 Context context = MyThreadLocal.get();

5 System.out.println(context.getTransactionId());

6 }

7 }

48304ba5e6f9fe08f3fa1abda7d326ab.png

程序输出:

set thread [Thread-0] contextid to 32

set thread [Thread-1] contextid to 89

32

89

三、总结

ThreadLocal使用步骤

1.建立ThreadLocal容器对象A,其中对需要保存的属性进行封装。并提供相应的get/set方法(全部为static)

2.在客户端程序中,用A.setxxx, A.getXXX访问相应数据,即可保证每个线程访问的是自己独立的变量

参考文献:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值