首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > 编程 >

ThreadLocal种的理解与使用

2012-11-04 
ThreadLocal类的理解与使用在java线程中有一个很有作用的类ThreadLocal?在网上关于ThreadLocal的理解也相

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;}@Overridepublic 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的值为0null账户的i的值为1null账户的i的值为2null账户的i的值为3null账户的i的值为4null账户的i的值为5xby账户的i的值为6xby账户的i的值为7xby账户的i的值为8xby账户的i的值为9xby账户的i的值为0xby账户的i的值为1xby账户的i的值为2xby账户的i的值为3xby账户的i的值为4xby账户的i的值为5gengu账户的i的值为6gengu账户的i的值为7gengu账户的i的值为8gengu账户的i的值为9

?如果使用Account类那么会出现什么结果?

null账户的i的值为0null账户的i的值为1null账户的i的值为2null账户的i的值为3null账户的i的值为4null账户的i的值为5xby账户的i的值为6xby账户的i的值为7xby账户的i的值为8xby账户的i的值为9null账户的i的值为0null账户的i的值为1null账户的i的值为2null账户的i的值为3null账户的i的值为4null账户的i的值为5gengu账户的i的值为6gengu账户的i的值为7gengu账户的i的值为8gengu账户的i的值为9

?不知道你们看出差别没有,就是后者相对非常独立,第一次accout变量的name属性改变之后没有使第二个线程中的account name变量改变。还是null,这回应该有点了解了吧。第一次运行的时候,线程1改变了线程2中account变量的name属性。

?

这样就好像,两个线程各拥有一个account实例一样。

?

但是ThreadLocal不能替代同步机制,因为他不能解决同步问题,只能解决共享安全问题,从根本上避免了多个线程之间的资源共享,所以也就不需要同步了。

?

?

热点排行