在java线程中有一个很有作用的类ThreadLocal
在网上关于ThreadLocal的理解也相当的多,文章也很多,但是很多看了都让人一头雾水,有的就讲原理,有的就说概念,而且大量的转载,却很少有实例这块的。
JDK1.5之后,java引入了泛型的概念,也为ThreadLocal引入了泛型,通过泛型可以简化多线程编程时的并发访问,使用这个工具类可以很简洁的编写出有没的多线程程序。
ThreadLocal 是Thread Local Variable(线程局部变量)的意思,线程局部变量的功能非常简单,就是为每一个使用该变量的线程都提供一个变量值的副本,使每一个想成都可以独立的改变自己的副本,而不会和其他线程的副本冲突,从线程的角度看,就好像每一个线程都完全拥有该变量
ThreadLocal 类的用法很简单,它只提供了三个方法。
T get();返回此线程局部变量中当前线程副本中的值。
void remove();删除此线程局部变量中当前线程副本中的值。
void set(T value);设置此线程局部变量中当前线程副本中的值。
下面将通过两个程序的对比来说明ThreadLocal类的作用。
下面提供两个账户类
package test7;
public class Account {
/**
* 定义一个ThreadLocal类变量
* 该变量将是一个线程局部变量,每个线程都会保留该变量的一个副本
*/
private ThreadLocal<String> name = new ThreadLocal<String>();
public String getName() {
return this.name.get();
}
public void setName(String name) {
this.name.set(name);
}
}
package test7;
public class Account1 {
/**
* 定义一个ThreadLocal类变量
* 该变量将是一个线程局部变量,每个线程都会保留该变量的一个副本
*/
private String name ;
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
}
以上的账户类中只有name这一个属性,不同的是前者使用了ThreadLocal来存贮,后者就是一个String
下面是线程类
package test7;
public class Thread2 extends Thread{
private Account1 account;
public Thread2(Account1 account,String name){
super(name);
this.account = account;
}
@Override
public void run(){
for (int i = 0; i < 10; i++) {
//当i为6的时候将当前账户名换成当前线程名
if(i == 6){
this.account.setName(getName());
}
System.out.println(account.getName()+"账户的i的值为"+i);
}
}
}
这个类,是对每个账户进行操作,当运行到6的时候就将账户名改为当前线程的名字(getName()是Thread类中定义的方法)。
场景类是这样的
package test7;
public class Test7 {
public static void main(String[] args) {
Account1 account = new Account1();
Thread thread1 = new Thread2(account,"xby");
Thread thread2 = new Thread2(account,"gengu");
thread1.start();
thread2.start();
}
}
如果使用Account1的话会出现什么结果?
null账户的i的值为0
null账户的i的值为1
null账户的i的值为2
null账户的i的值为3
null账户的i的值为4
null账户的i的值为5
xby账户的i的值为6
xby账户的i的值为7
xby账户的i的值为8
xby账户的i的值为9
xby账户的i的值为0
xby账户的i的值为1
xby账户的i的值为2
xby账户的i的值为3
xby账户的i的值为4
xby账户的i的值为5
gengu账户的i的值为6
gengu账户的i的值为7
gengu账户的i的值为8
gengu账户的i的值为9
如果使用Account类那么会出现什么结果?
null账户的i的值为0
null账户的i的值为1
null账户的i的值为2
null账户的i的值为3
null账户的i的值为4
null账户的i的值为5
xby账户的i的值为6
xby账户的i的值为7
xby账户的i的值为8
xby账户的i的值为9
null账户的i的值为0
null账户的i的值为1
null账户的i的值为2
null账户的i的值为3
null账户的i的值为4
null账户的i的值为5
gengu账户的i的值为6
gengu账户的i的值为7
gengu账户的i的值为8
gengu账户的i的值为9
不知道你们看出差别没有,就是后者相对非常独立,第一次accout变量的name属性改变之后没有使第二个线程中的account name变量改变。还是null,这回应该有点了解了吧。第一次运行的时候,线程1改变了线程2中account变量的name属性。
这样就好像,两个线程各拥有一个account实例一样。
但是ThreadLocal不能替代同步机制,因为他不能解决同步问题,只能解决共享安全问题,从根本上避免了多个线程之间的资源共享,所以也就不需要同步了。
分享到:
相关推荐
理解ThreadLocal 理解ThreadLocal 理解ThreadLocal 理解ThreadLocal
ThreadLocal应用示例及理解,这个写了相关的示例,可以参考一下。
ThreadLocal深度理解
正确理解ThreadLocal.pdf
Java中ThreadLocal工具类(解决多线程程序中并发问题的一种新思路,主要为参数的拷贝问题),感兴趣的话可以查看博文,博文地址:http://blog.csdn.net/otengyue/article/details/38459327
NULL 博文链接:https://aty.iteye.com/blog/1913734
ThreadLocal的简单理解.doc
ThreadLocal为解决多线程程序的并发问题提供了一种新的思路。使用这个工具类可以很简洁地编写出优美的多线程程序,ThreadLocal并不是一个Thread,而是Thread的局部变量
主要介绍了深入理解ThreadLocal工作原理及使用示例,涉及ThreadLocal<T> 简介和使用示例及ThreadLocal的原理等相关内容,具有一定参考价值,需要的朋友可以了解下。
主要介绍了Android 中ThreadLocal的深入理解的相关资料,希望通过本文能帮助到大家,让大家理解应用ThreadLocal,需要的朋友可以参考下
并且由于每个线程在访问该变量时,读取和修改的,都是独有的那份变量拷贝,变量被彻底封闭在每个访问的线程中,并发错误出现的可能也完全消除了。} catch (SQL
主要介绍了彻底理解Java 中的ThreadLocal的相关资料,需要的朋友可以参考下
早在 JDK 1.2 的时代,java.lang.ThreadLocal 就诞生了,它是为了解决多线程并发问题而设计的,只不过设计得有些难用,所以至今没有得到广泛使用。其实它还是挺有用的,不相信的话,我们一起来看看这个例子吧。 一个...
主要介绍了Android 中 ThreadLocal使用示例的相关资料,这里提供示例代码帮助大家学习理解这部分内容,需要的朋友可以参考下
ThreadLocal翻译成中文比较准确的叫法应该是:线程局部变量。使用这个工具类可以很简洁地编写出优美的多线程程序。接下来通过本文给大家介绍Java中的ThreadLocal,需要的朋友可以参考下
但是使用ThreadLocal对象去存储一个共享资源时,每一个线程的副本变量都指向同一个共享资源,这里也是会存在线程安全问题的。 ThreadLocal设计初衷:提供线程内部的局部变量,在本线程内随时随地可取,隔离其他线程...
声明仅作学习。如有不适,请告知。清晰的看到一个线程Thread中存在一个ThreadLocalMap,ThreadLocalMap中的key对应ThreadLo
NULL 博文链接:https://beijishiqidu.iteye.com/blog/2247342