当前位置:嗨网首页>书籍在线阅读

31-运用原子性数组

  
选择背景色: 黄橙 洋红 淡粉 水蓝 草绿 白色 选择字体: 宋体 黑体 微软雅黑 楷体 选择字体大小: 恢复默认

7.9 运用原子性数组

考虑到实现一个并发应用程序时至少会有一个对象共享于几个线程。在这种场景下,就必须使用同步机制来对共享对象的字段进行访问保护(例如锁或关键字 synchronized ),以此来避免数据不一致的问题。

但这些机制有如下问题。

  • 死锁:出现该情况是由于一个线程为了等待一个锁而被阻塞,但持有该锁的其他线程永不释放它。在这种情况下,这会阻塞程序以致它永远不会执行完成。
  • 如果只有一个线程访问该共享对象,则它必须执行必要的代码来获取和释放锁。

为了在这些情况下能提供更好的性能,Java开发了 compare-and-swap 操作。该操作采用如下步骤来修改变量的值。

1.先获取变量的旧值。

2.把变量的值变更为一个临时变量的新值。

3.如果旧值与变量的实际值相等,则替换旧值为新值。如果其他线程已经改变该旧值,则它可能与实际值不一致。

在这种机制下,就不需要同步机制了,因此这可以避免死锁并且获得更好的性能。但该机制也有缺陷。该操作必须从任何边际效应中释放出来,因为它们可能会通过高度满足资源的活锁来进行重试。与标准锁进行对比,对于性能来说,它们通常也更难监控。

Java在 原子性变量 中实现了这种机制。这些变量提供了 compareAndSet() 方法(它具备compare-and-swap操作实现)和其他方法。

Java还提供 原子性数组 ,以允许原子性操作整型和长整型数值的数组。在本节,将会学习如何使用 AtomicIntegerArray 类来操作原子性数组。考虑到如果用的是 AtomicInteger[] ,则它并非是线程安全的对象。一个独立的 AtomicInteger 对象是线程安全的,但其数组形式的数据结构则不是。