面试题:线程安全3问
Posted 格子衫111
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了面试题:线程安全3问相关的知识,希望对你有一定的参考价值。
一、一共有哪 3 类线程安全问题?
什么是线程安全:
当多个线程访问一个对象时,不需要考虑不能同时写入或者读写不能并行的问题,也不需要做额外的同步操作,那么就说这个对象是线程安全的。
1)运行结果错误:如两个线程同时访问共享变量i,执行1000次 i++操作,未加同步操作;
2)发布和初始化引发的线程安全问题:如子线程还未给一个对象初始化,主线程就去访问,得到的是null;
3)活跃性问题,
死锁:如两个线程各拿到对方的锁不愿意释放;
活锁:如消息队列中报错的消息被重复放到队列头进行执行;
饥饿:如某个线程优先级被设置很低(1最低),导致一直获取不到CPU资源无法运行。
二、哪些场景需要额外注意线程安全问题?
1)访问共享变量或缓存时:如两个线程同时对全局变量进行i++操作;
2)依赖时序的操作:如单例对象懒汉式创建时的双重校验;
3)不同数据之间存在绑定关系:如IP和端口号,需要绑定在一起成为一个原子操作;
4)访问了线程不安全的对象:如ArrayList。
三、为什么多线程会带来性能问题?
什么是性能问题:
比如服务器的响应慢、吞吐量低、内存占用过多就属于性能问题。
线程调度开销:
上下文切换:
操作系统会按照一定的调度算法,给每个线程分配时间片,上下文切换会挂起当前线程,寻找下一处即将恢复的代码。假如执行的任务比较简单,可能导致线程调度的开销比实际执行的内容还要大。
缓存失效:
当前一个任务缓存好内容后,切换到另外一个线程,随后再切换回来,刚刚缓存的内容不见啦,又得重新计算,这就是线程调度所带来的缓存失效。
ps:为了避免频繁进行上下文切换,线程调度器会给被调度的线程设置最小执行时间。
线程协作开销:
多线程协作时,往往为了线程安全,可能会禁止编译器或者CPU指令重排序(如violate),为了数据的内存可见性,可能会在线程工作内存和主存中来回反复flash,带来性能开销。
以上是关于面试题:线程安全3问的主要内容,如果未能解决你的问题,请参考以下文章