ThreadLocal,线程本地变量
2016-09-03 13:05
357 查看
什么是ThreadLocal?
JAVA为线程安全提供了同步监视器、同步锁和 volatile关键字外,还提供了一些工具类,如ThreadLocal类,它代表一个线程局部变量,通过把数据放在ThreadLocal中就可以让每条线程创建一个该变量的副本,从而避免并发访问的线程安全问题。
(注意,同步监视器和同步锁与ThreadLocal的设计目的不一样,前者是让竞争资源共享,但是保证每个临界区都只有一个线程;后者是将资源复制一份给不同的线程)
另一个解释:
ThreadLocal 用于创建线程的本地变量,我们知道一个对象的所有线程会共享它的全局变量,所以这些变量不是线程安
全的,我们可以使用同步技术。但是当我们不想使用同步的时候,我们可以选择 ThreadLocal 变量。
每个线程都会拥有他们自己的 Thread 变量,它们可以使用 get()\set()方法去获取他们的默认值或者在线程内部改变他们
的值。ThreadLocal 实例通常是希望它们同线程状态关联起来是 private static 属性。在 ThreadLocal 例子这篇文章中你
可以看到一个关于 ThreadLocal 的小程序。
下面看一个例子:
输出如图:
分析程序:这个程序共有3个线程,一个是main线程,一个是线程甲,一个是线程乙;其中这三个线程都有Account变量是三个线程共享的,account里面有两个变量,一个是线程本地变量name,一个是普通变量age,我们从输出可以看到,age一直都是11,而name一开始是null,知道被赋值为线程名,这是因为即使在main线程里面为他们共同享有的account的name初始化为”初始化名”,但由于name是线程本地变量,所以他们在自己的线程体里面都是自己的name副本的值,而这个name副本的值就是null
JAVA为线程安全提供了同步监视器、同步锁和 volatile关键字外,还提供了一些工具类,如ThreadLocal类,它代表一个线程局部变量,通过把数据放在ThreadLocal中就可以让每条线程创建一个该变量的副本,从而避免并发访问的线程安全问题。
(注意,同步监视器和同步锁与ThreadLocal的设计目的不一样,前者是让竞争资源共享,但是保证每个临界区都只有一个线程;后者是将资源复制一份给不同的线程)
另一个解释:
ThreadLocal 用于创建线程的本地变量,我们知道一个对象的所有线程会共享它的全局变量,所以这些变量不是线程安
全的,我们可以使用同步技术。但是当我们不想使用同步的时候,我们可以选择 ThreadLocal 变量。
每个线程都会拥有他们自己的 Thread 变量,它们可以使用 get()\set()方法去获取他们的默认值或者在线程内部改变他们
的值。ThreadLocal 实例通常是希望它们同线程状态关联起来是 private static 属性。在 ThreadLocal 例子这篇文章中你
可以看到一个关于 ThreadLocal 的小程序。
下面看一个例子:
package cn.test.thread.thread_Local; class Account{ //创建一个线程本地变量name private ThreadLocal<String> name = new ThreadLocal<String>(); private int age; public int getAge() { return age; } public void setAge(int age) { this.age = age; } public Account(String name, int age){ this.name.set(name); this.age = age; } public String getName() { return name.get(); } public void setName(String name) { this.name.set(name); } } class MyTest extends Thread{ private Account account; public MyTest(Account account, String name){ super(name); this.account = account; } public MyTest(String name){ super(name); } public void run(){ for(int i = 0; i < 10; i++){ if(6 == i){ account.setName(getName()); } System.out.println("name:"+account.getName() + " " + "age:" + account.getAge() + "账户i的值:" + i); } } } public class ThreadLocalTest { public static void main(String[] args) { Account account = new Account("初始化名", 11); System.out.println("**************"+account.getName()); new MyTest(account, "线程甲").start(); new MyTest(account, "线程乙").start(); } }
输出如图:
**************初始化名 name:null age:11账户i的值:0 name:null age:11账户i的值:0 name:null age:11账户i的值:1 name:null age:11账户i的值:1 name:null age:11账户i的值:2 name:null age:11账户i的值:2 name:null age:11账户i的值:3 name:null age:11账户i的值:3 name:null age:11账户i的值:4 name:null age:11账户i的值:4 name:null age:11账户i的值:5 name:null age:11账户i的值:5 name:线程甲 age:11账户i的值:6 name:线程乙 age:11账户i的值:6 name:线程甲 age:11账户i的值:7 name:线程乙 age:11账户i的值:7 name:线程甲 age:11账户i的值:8 name:线程乙 age:11账户i的值:8 name:线程甲 age:11账户i的值:9 name:线程乙 age:11账户i的值:9
分析程序:这个程序共有3个线程,一个是main线程,一个是线程甲,一个是线程乙;其中这三个线程都有Account变量是三个线程共享的,account里面有两个变量,一个是线程本地变量name,一个是普通变量age,我们从输出可以看到,age一直都是11,而name一开始是null,知道被赋值为线程名,这是因为即使在main线程里面为他们共同享有的account的name初始化为”初始化名”,但由于name是线程本地变量,所以他们在自己的线程体里面都是自己的name副本的值,而这个name副本的值就是null
相关文章推荐
- 线程本地变量ThreadLocal
- 线程本地变量:ThreadLocal
- Java线程外篇:线程本地变量ThreadLocal
- Java并发编程---ThreadLocal(线程本地变量、线程本地存储)
- Java线程(篇外篇):线程本地变量ThreadLocal
- Java线程(篇外篇):线程本地变量ThreadLocal
- Java线程(篇外篇):线程本地变量ThreadLocal
- Java线程(篇外篇):线程本地变量ThreadLocal
- Java线程(篇外篇):线程本地变量ThreadLocal
- 线程本地变量ThreadLocal
- 深入理解线程本地变量ThreadLocal
- Java线程(篇外篇):线程本地变量ThreadLocal
- Java Concurrency - ThreadLocal, 本地线程变量
- 线程本地变量ThreadLocal (耗时工具)
- JAVA线程本地变量ThreadLocal和私有变量的区别
- 线程本地变量ThreadLocal
- Java线程(篇外篇):线程本地变量ThreadLocal
- Java线程(篇外篇):线程本地变量ThreadLocal
- 线程本地变量ThreadLocal源码解读
- ThreadLocal 线程本地变量