壹影博客.
我在下午4点钟开始想你
Java并发编程-如何保证线程安全
  • 2024-3-9日
  • 0评论
  • 279围观

Java并发编程-如何保证线程安全

 什么是并发安全性问题?我们要先理解什么是线程安全性

线程安全性:我们所写的代码在并发情况下使用时,总是能表现出正确的行为;反之,未实现线程安全的代码,表现的行为是不可预知的,有可能正确,而绝大多数的情况下是错误的。

降低发生线程安全性问题的措施

一、线程封闭:就是把对象封装到一个线程里,只有这一个线程能看到此对象。那么这个对象就算不是线程安全的也不会出现任何安全问题。

 线程封闭有如下几种方式:

1.栈封闭:学过JVM的我们都知道,栈内的栈帧中存放有局部变量表,做线程封闭说白了就是把变量换成局部变量, 这个 过程 叫做栈封闭,简单的说就是局部变量。多个线程访问一个方法,此方法中的局部变量都会被拷贝一份到
线程栈中。所以局部变量是不被多个线程所共享的,也就不会出现并发问题。所以能用局部变量就别用全局的变量,全局变量容易引起并发问题。

2.TheadLocal:ThreadLocal是实现线程封闭的最好方法。ThreadLocal内部维护了一个Map,Map的key是每个线程的名称,而Map的值就是我们要封闭的对象。每个线程中的对象都对应着Map中一个值,也就是ThreadLocal利用Map实现了对象的线程封闭。

二、无状态的类

什么是无状态的类呢,其实就是没有任何成员变量的类,就叫无状态的类,这种类一定是线程安全的。
追问:如果这个类的方法参数中使用了对象,也是线程安全的吗?答:是的,因为类的方法参数使用了对象,我们正在使用的这个类的安全性取决于你传入的参数对象,如果你传入的对象本身就是安全的那么这个类一定是安全的,这与方法无关,与传递的对象有关,多以对于我们类的方法参数中使用了对象 那么是线程安全的.

三、让类不可变

让状态不可变,加final关键字,对于一个类,所有的成员变量应该是私有的,同样的只要有可能,所有的成员变量应该加上final关键字,但是加上final,要注意如果成员变量又是一个对象时,这个对象所对应的类也要是不可变,才能保证整个类是不可变的。
但是要注意,一旦类的成员变量中有对象,上述的final关键字保证不可变并不能保证类的安全性,为何?因为在多线程下,虽然对象的引用不可变,但是对象在堆上的实例是有可能被多个线程同时修改的,没有正确处理的情况下,对象实例在堆中的数据是不可预知的。

public class ImmutableClass{
 private final int a;
 private final String b;
 private final UserVo user; //加上引用对象后就不安全了
}

 四、加锁和CAS

我们最常使用的保证线程安全的手段,使用synchronized关键字,使用显式锁,使用各种原子变量,修改数据时使用CAS机制等等。

很高兴您能看到这里,希望这篇文章对您学习并发编程有所帮助,如果本篇文章有什么错误或者遗漏的地方还望联系指正,QQ203455278

by 壹影

发表评论