线程简介及安全性

1. 线程的优点

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

2. 线程带来的风险

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

3. 线程安全性

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

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

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

public void synchronized count() {
    
    
	.....
}

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

3.2 活跃性与性能

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

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

猜你喜欢

转载自blog.csdn.net/SJshenjian/article/details/130188731