并发编程的艺术之读书笔记(十三)
程序员文章站
2022-05-13 15:03:41
...
前言:
上一部分,我们一起学习了java中的Fork/Join框架,这一部分,我们来一起学习java中的原子类
我们知道当多个线程同时更新一个变量,可能会导致更新不同步的问题,比如变量i=1,有两个线程A和B,A操作i=i+1,B操作i=i+1,预期得到i=3,结果i却等于2,那是因为A和B线程在更新i时拿到的i都是1,这就是多线程导致的不同步问题,为了解决这个问题,我们一般会使用synchronized关键字,它会保证多线程操作的同步。那么还有没有更简便的方法可以实现我们的要求呢,java从jdk1.5开始在并发包里增加了一个Atomic包,这个包下的类都是原子操作类,底层用CAS保证了操作的原子性,也就不会发生多线程下不同步的问题了。下面就来一起看一下
1. 原子更新基本类型
原子方式更新的基本类型,分为3种
- AtomicBoolean 原子更新布尔类型
- AtomicInteger 原子更新整形
- AtomicLong 原子更新长整型
接着我们介绍一些常用方法,以最常用的AtomicInteger为例
-
int addAndGet(int delta),原子方式将输入的值与实例中的值相加,并返回结果
-
boolean compareAndSet(int expect, int update),比较并设置值,如果输入的数值等于预期值,那么用原子方式将该值设置为输入的值
-
int getAndIncrement(),原子方式把当前值加1,返回自增前的值
-
void lazySet(int newValue),最终会设置成newValue
-
int getAndSet(int newValue),原子方式设置为newValue的值,返回旧值
2. 原子更新数组
- AtomicIntegerArray 原子更新整形数组
- AtomicLongArray 原子更新长整型数组
- AtomicReferenceArray 原子更新引用类型数组
主要方法如下:
-
int addAndGet(int i, int delta),原子方式将输入值与数组中索引i位置的元素相加
-
boolean compareAndSet(int i, int expect, int update),如果当前值等于预期值,则以原子方式将数组位置i的元素设置成update值
3. 原子更新引用类型
- AtomicReference 原子更新引用类型
- AtomicReferenceFieldUpdater 原子更新引用类型里的字段
- AtomicMarkableReference 原子更新带有标记位的引用类型
4. 原子更新字段类
- AtomicIntegerFieldUpdater: 原子更新整型的字段的更新器
- AtomicLongFieldUpdater: 原子更新长整型字段的更新器
- AtomicStampedFieldUpdater: 原子更新带有版本号的引用类型
- AtomicReferenceFieldUpdater: 上面已经说过此处不再赘述
要想原子地更新字段类需要两步。第一步,因为原子更新字段类都是抽象类,每次使用的时候必须使用静态方法newUpdater()创建一个更新器,并且需要设置想要更新的类和属性。第二步,更新类的字段必须使用public volatile修饰。下面来演示一下
public class AtomicIntegerUpdateField {
private static AtomicIntegerFieldUpdater<User> a =
AtomicIntegerFieldUpdater.newUpdater(User.class, "old");
public static void main(String[] args) {
//设置柯南的年龄是10岁
User conan = new User("conan", 10);
//长了一岁,但是会输出旧的年龄
System.out.println(a.getAndIncrement(conan));
//现在的年龄
System.out.println(a.get(conan));
}
static class User {
private String name;
public volatile int old;
public User(String name, int old) {
this.name = name;
this.old = old;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getOld() {
return old;
}
public void setOld(int old) {
this.old = old;
}
}
}
总结
本部分我们学习了java中的原子类的概念以及使用方式,下一部分我们开始学习java的并发工具类
上一篇: wifi认证 跳转不到登录页解决办法
下一篇: 何位大侠做过会话劫持
推荐阅读
-
《C#并发编程经典实例》读书笔记-关于并发编程的几个误解
-
python 之 并发编程(非阻塞IO模型、I/O多路复用、socketserver的使用)
-
Java并发编程的艺术-----Java并发编程基础(线程间通信)
-
《Java 编程思想》读书笔记之并发(一)
-
《Java并发编程的艺术》笔记
-
【响应式编程的思维艺术】 (4)从打飞机游戏理解并发与流的融合
-
<
>-阅读笔记和思维导图 -
JAVA并发编程(三):同步的辅助类之闭锁(CountDownLatch)与循环屏障(CyclicBarrier)
-
Java多线程并发编程中并发容器第二篇之List的并发类讲解
-
并发编程(十三)—— Java 线程池 实现原理与源码深度解析 之 Executors(三)