盒子
盒子
文章目录
  1. 1. 线程的优点
  2. 2. 线程带来的风险
  3. 3. 线程安全性
    1. 3.1 内置锁与重入
    2. 3.2 活跃性与性能

线程简介及安全性

1. 线程的优点

1)发挥多处理器的强大功能
2)建模的简单性 为模型中的每种类型任务都分配一个专门的线程
3)异步事件的简化处理
4)响应更灵敏的用户界面

2. 线程带来的风险

1)安全性问题
2)活跃性问题 如发生死锁,无限等待
3)性能问题 如频繁的上下文切换:保存与恢复上下文,丢失局部性,CPU花在线程切换上更多开销而不是线程上;如同步机制,抑制某些编译器优化,使内存缓存区内存无效,增加共享内存总线流量

3. 线程安全性

如果当多个线程访问同一个可变的状态变量时没有使用合适的同步,那么程序就会出现错误。有三种方式可以修复这个问题:
√ 不在线程之间共享该变量
√ 将状态变量修改为不可变变量
√ 在访问状态变量时使用同步

1
2
无状态对象一定是线程安全的。
无状态对象:他既不包含任何域,也不包含对其他类中域的引用
1
2
竞态条件: 由于不恰当的执行时序而出现的不正确的结果
竞态条件出现常见操作: 先检查后执行,如延迟初始化; 读取-修改-写入, 如i++

3.1 内置锁与重入

JAVA中提供了一种内置锁机制支持原子性:同步代码块
同步代码块分为两部分:
1)锁的对象引用 synchronized (lock) { }
2)锁保护的代码块

1
2
3
public void synchronized count() {
.....
}

内置锁是可重入的,如果某个线程试图获得该线程已经获得的锁,那么该请求会成功
重入实现方式: 为每个锁关联一个获取计数器与一个所有者线程,线程进入则+1,线程退出则-1。当计数器为0,该锁将被释放

3.2 活跃性与性能

当实现某个同步策略时,一定不要盲目为了性能而牺牲简单性(这可能会破环安全性)

当执行时间较长的计算或者可能无法完成的操作时(例如,网络I/O或控制台I/O),一定不要持有锁

支持一下
扫一扫,支持沈健
  • 微信扫一扫
  • 支付宝扫一扫