面试题:线程安全3问

一、一共有哪 3 类线程安全问题?

什么是线程安全:

当多个线程访问一个对象时,不需要考虑不能同时写入或者读写不能并行的问题,也不需要做额外的同步操作,那么就说这个对象是线程安全的。

1)运行结果错误:如两个线程同时访问共享变量i,执行1000次 i++操作,未加同步操作;

2)发布和初始化引发的线程安全问题:如子线程还未给一个对象初始化,主线程就去访问,得到的是null;

3)活跃性问题

死锁:如两个线程各拿到对方的锁不愿意释放;

活锁:如消息队列中报错的消息被重复放到队列头进行执行;

饥饿:如某个线程优先级被设置很低(1最低),导致一直获取不到CPU资源无法运行。


二、哪些场景需要额外注意线程安全问题?

1)访问共享变量或缓存时:如两个线程同时对全局变量进行i++操作;

2)依赖时序的操作:如单例对象懒汉式创建时的双重校验;

3)不同数据之间存在绑定关系:如IP和端口号,需要绑定在一起成为一个原子操作;

4)访问了线程不安全的对象:如ArrayList。


三、为什么多线程会带来性能问题?

什么是性能问题:

比如服务器的响应慢、吞吐量低、内存占用过多就属于性能问题。

线程调度开销:

上下文切换:

操作系统会按照一定的调度算法,给每个线程分配时间片,上下文切换会挂起当前线程,寻找下一处即将恢复的代码。假如执行的任务比较简单,可能导致线程调度的开销比实际执行的内容还要大。

缓存失效:

当前一个任务缓存好内容后,切换到另外一个线程,随后再切换回来,刚刚缓存的内容不见啦,又得重新计算,这就是线程调度所带来的缓存失效。

ps:为了避免频繁进行上下文切换,线程调度器会给被调度的线程设置最小执行时间。

线程协作开销:

多线程协作时,往往为了线程安全,可能会禁止编译器或者CPU指令重排序(如violate),为了数据的内存可见性,可能会在线程工作内存和主存中来回反复flash,带来性能开销。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值