java ThreadLocal保护线程的局部变量

如何保证java局部变量的安全?

 

一、什么是线程中的局部变量

1.区分线程类中的局部变量和方法中的局部变量

我的理解:

2.局部变量

多个线程对同一个对象的局部变量进行操作时,它们对该局部变量是彼此影响的。也就是说,一个线程对局部变量的改变会影响到另一个线程。

所以,如果在线程类中定义一个局部变量,那就是你希望和其他的线程一起共享这个局部变量。

尝试运行:

结果为:

这说明thread1和thread2共享varThread对象中的局部变量i。

这样写其实是不安全的,变量i不具有原子性,在并发条件下可能会发生错误。应该使用AtomicInteger。

2.方法中的局部变量

每当启动一个新线程时,java虚拟机都会为它分配一个java栈,java栈上的所有数据都是此线程私有的。任何线程都不能访问另一个线程的栈数据,因此我们不需要考虑多线程情况下栈数据的访问同步问题。

当一个线程调用一个方法的时候,方法的局部变量保存在调用线程的java栈的桢中,只有一个线程能访问那些局部变量,即调用方法的线程。

每启动一条线程,都会分配线程自己的栈。这个线程里面所涉及的对象方法,每个方法由一个栈帧,用来存放方法中的局部变量,中间结果和操作数。也就是说,方法中的局部变量在不同线程的栈帧中,所以不会相互影响。

所以,如果在线程类中的run方法中定义一个局部变量,那你肯定不希望有别的线程可以操作它。

尝试运行:

结果为:

这说明thread1和thread2都有自己私有的局部变量i,彼此之间不能共享。

二、如何保证局部变量的安全?

保证局部变量的安全,其实就是不希望当前线程的局部变量能够被其他线程访问/操作,即实现局部变量的私有化。

但是,如上文所说,如果在线程类中定义一个局部变量,基本上就是希望线程之间能够共享这个成员变量。为了实现局部变量的私有化,必须做一些处理:

结果为:

这证明局部变量i已经被当前线程私有化了。

使用ThreadLocal类,可以定义局部变量的数据类型,实现局部变量的私有化。同时,取值和赋值都需要通过ThreadLocal提供的方法实现。

主要用到的基本上就是initialValue、get、set、remove四个方法,顾名思义。

三、总结

暂时还没有遇上使用ThreadLocal的场景,回头再看看。

发表评论

电子邮件地址不会被公开。 必填项已用*标注