多线程感悟及最佳实践

首先,我们应该明白,线程安全问题会在什么时候出现,一句话:“在多个线程共享同一个资源,并且对于这个资源的修改和访问在同一个方法中,此时就会出现线程安全问题”。举个例子,在访问共享资源的方法A中,有两个方法操作共享资源,方法名分别是X和Y,X是修改共享资源,Y是访问共享资源,这两个方法在同一个方法A中,这个方法A就不具有原子操作性,因为A有两个步骤。
那么,线程安全分为几种情况呢?我的体会是有以下几种情况:
第一,java提供的类是否是线程安全的,例如,ArrayList就是线程不安全的,但是Vector就是线程安全的。有的人会问,这个线程安全到底是个什么含义呢?比如说有一个add方法,是添加元素的,对于ArrayList而言是线程不安全的,也就是说,当add方法不是原子操作的时候,会出现线程安全问题,对于add方法而言,有两个步骤,第一个步骤是添加元素,第二个步骤是将size加1,如果是ArrayList,当两个线程同时进行第一个步骤,而同时在更新size的时候,取到的size为0,那么在更新的时候,最终的size就会变成1,但是其实应该为2,但是Vector这个类的add方法是线程安全的,就不会出现这样的错误。
第二,如果在类的外部,比如说Vector有两个方法add和size,这两个方法被我们使用放到一个方法C中,即使Vector本身是线程安全的,方法C也是线程不安全的,因为方法C不是原子性操作。
那么线程安全有几种应用场景呢?
第一,一个对象是单例的,它的成员变量就是共享资源,当多个线程访问时,就会出现线程安全问题。
第二,一个对象,即使不是单例的,但是这个对象存在static的变量,也会存在线程安全问题。
那么,我们怎样解决线程安全问题呢?有几个最佳实践的方法:
第一,尽量少使用成员变量,尽量使用方法内的局部变量,为什么呢?因为局部变量的生命周期是在方法内,如果实在想使用成员变量,这个成员变量如果是只读的,也不会出现线程安全问题。
第二,在多线程环境下,尽量使用线程安全的类,保证不会因类的方法不具有同步性而造成线程安全问题。同时,在使用同步的时候,要注意性能,比如多使用java并发包中的类。同时我们还需要注意一个隐藏的东西,一般的jvm在对于赋值的时候是32位bit一起赋值的,当你使用的类型是64bit或者更多bit的时候,赋值不是一个原子操作,例如long是64bit的,所以赋值的时候是先赋值32个bit,再赋值另外32个bit,很显然这个赋值过程不是原子的,因此会存在线程安全问题,因此我们要使用线程安全的long。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值