什么叫线程安全&从哪里考虑
线程安全的对象
一个比较专业的描述是:
当多个线程访问一个对象时,如果不用进行额外的同步控制或其它的协调操作,调用这个对象的行为都可以获得正确的结果,我们就说这个对象是线程安全的。
也就是这个对象的内部采用锁机制或其他的方式保证了多线程同时访问时的数据的安全
什么时候需要考虑线程的安全
这里共有三点:
- 多线程的环境下
- 多个线程共用一个对象
- 这个对象是有状态的 (属性是可变的)
线程安全的解决方案
从以上的三点出发,破坏其中的任意一个条件,我们都可以保证线程的安全,而不用考虑这个对象的线程安全与否以及是否需要增加额外的操作来保证线程安全。
- 使用单线程,破坏了第一个条件:简单的单线程的测试,平时的算法的编写,在一个线程内,根本不用考虑线程的安全
- 一个线程独占一个某类的对象(或者是某个对象数据的副本,只要无交集即可),形成线程封闭,破坏了第二个条件:这个考虑在java中有应用,比如
- 栈封闭:局部变量,无线程安全问题
- ThreadLocal线程封闭:非常好的封闭方法
- Ad-hoc线程封闭:程序控制实现(程序员自组织的),非常糟糕,不建议使用
- 使用不可变对象,确保对象是无状态的,破环第三个条件:典型的例子String,因为其无法改变,所以不可能对其尝试修改,是常量,唯一有用的对其的操作是读(没有了拿份到缓存用,有了就不用拿了,反正不变,绝对安全)
- 不可变对象需要满足的条件
- 对象创建以后其状态就不能修改
- 对象所有域都是final类型(对此题来讲,破坏第三个条件,严格来讲若该对象的内部组合了其它对象,那么也必须保证其是不可变对象,递归下去;否则只保证了组合的对象的引用不变,但是对象的属性可变,仍然是有状态的;比如一个人,它有一个心脏,心脏还是哪个心脏,没变,但是心脏得病了,心脏的属性变了,这个人的状态一定是变了)
- 对象是正确创建的(在对象创建时期,this引用没有逸出)
- 不可变对象需要满足的条件
考虑线程安全
上面三点全都满足,即是可能出现线程安全的问题的,需要考虑线程安全。如果使用了线程安全的类,不需要额外的操作来保证线程的安全;否则,则需要采用给代码块加锁或者其它的一些方式来保证数据的安全。
什么叫线程安全&从哪里考虑
https://blog.wangxk.cc/2020/10/06/什么叫线程安全-从哪里考虑/