ThreadLocal类的理解与使用

在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不能替代同步机制,因为他不能解决同步问题,只能解决共享安全问题,从根本上避免了多个线程之间的资源共享,所以也就不需要同步了。

 

 

1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看REAdMe.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看REAdMe.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看READme.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值