廖雪峰Java11多线程编程-3高级concurrent包-5Atomic
1. Atomic
java.util.concurrent.atomic提供了一组原子类型操作。如AtomicInteger提供了
int addAndGet(int delta)
int incrementAndGet()
int get()
int compareAndGet()
1.1 无锁线程安全
Atomic类可以实现无锁(lock-free)的线程安全(thread-safe)访问
原理:CAS(Compare and Set)如果AtomicInteger实例的值是prev,就替换为next,返回true;否则,返回false
```#java
/*
* 在这个操作中,如果AtomicInteger当前的值是prev,就更新为next,返回true,终止循环;
* 如果AtomicInteger当前的值不等于prev,就什么也不做,返回false,继续循环。
*/
public int add1AndGet(AtomicInteger var){
int prev, next;
do{
prev = var.get(); //之后其他的线程修改了prev的值,也不影响结果
next = prev + 1;
}while ( ! var.compareAndSet(prev, next));
return prev;
}
```
利用CAS操作,可以保证,即时在do while循环中,其他的线程在prev = var.get()后修改了AtomicInteger的值,最终结果也一定是正确的。
### 1.2 incrementAndGet
通常不需要直接使用do...while..来调用compileAndGet,而是用incrementAndGet()这种封装的方法。
```#java
AtomicLong var = new AtomicLong(0);
public long getNextId(){ //多线程安全的id序列生成器
return var.incrementAndGet();
}
```
## 2.示例
```#java
import java.util.concurrent.atomic.AtomicInteger;
class Counter{
private AtomicInteger value = new AtomicInteger();
//add、dec、get不再使用synchronized或ReentrantLock加锁,因为Atomic本身就是原子操作
public int add(int m){
return this.value.addAndGet(m);
}
public int dec(int m){
return this.value.addAndGet(-m);
}
public int get(){
return this.value.get();
}
}
public class Main{
final static int LOOP = 100;
public static void main(String[] args) throws InterruptedException{
Counter counter = new Counter();
Thread t1 = new Thread(){
public void run(){
for(int i=0;i<LOOP;i++) {
counter.add(1);
}
}
};
Thread t2 = new Thread(){
public void run(){
for(int i=0;i<LOOP;i++){
counter.dec(1);
}
}
};
t1.start();
t2.start();
t1.join();
t2.join();
System.out.println(counter.get());
System.out.println("END");
}
}
<img src="https://img2018.cnblogs.com/blog/1418970/201906/1418970-20190613170947374-25418412.png" width="500" />
## 3.总结:
使用java.util.atomic提供的原子操作可以简化多线程编程
* AtomicInteger/AtomicLong/AtomicArray
* 原子操作实现了无锁的线程安全
* 适用于计数器、累加器
廖雪峰Java11多线程编程-3高级concurrent包-5Atomic的更多相关文章
- 廖雪峰Java11多线程编程-3高级concurrent包-4Concurrent集合
Concurrent 用ReentrantLock+Condition实现Blocking Queue. Blocking Queue:当一个线程调用getTask()时,该方法内部可能让给线程进入等 ...
- 廖雪峰Java11多线程编程-3高级concurrent包-1ReentrantLock
线程同步: 是因为多线程读写竞争资源需要同步 Java语言提供了synchronized/wait/notify来实现同步 编写多线程同步很困难 所以Java提供了java.util.concurre ...
- 廖雪峰Java11多线程编程-3高级concurrent包-6ExecutorService
Java语言内置多线程支持: 创建线程需要操作系统资源(线程资源,栈空间) 频繁创建和销毁线程需要消耗大量时间 如果可以复用一个线程 线程池: 线程池维护若干个线程,处于等待状态 如果有新任务,就分配 ...
- 廖雪峰Java11多线程编程-3高级concurrent包-9Fork_Join
线程池可以高效执行大量小任务: Fork/Join线程池可以执行一种特殊的任务: 把一个大任务拆成多个小任务并行执行 Fork/Join是在JDK 1.7引入的 示例:计算一个大数组的和 Fork/J ...
- 廖雪峰Java11多线程编程-3高级concurrent包-8CompletableFuture
使用Future可以获得异步执行结果 Future<String> future = executor.submit(task); String result = future.get() ...
- 廖雪峰Java11多线程编程-3高级concurrent包-7Future
JDK提供了ExecutorService接口表示线程池,可以通过submit提交一个任务. ExecutorService executor = Executors.newFixedThreadPo ...
- 廖雪峰Java11多线程编程-3高级concurrent包-3Condition
Condition实现等待和唤醒线程 java.util.locks.ReentrantLock用于替代synchronized加锁 synchronized可以使用wait和notify实现在条件不 ...
- 廖雪峰Java11多线程编程-3高级concurrent包-2ReadWriteLock
ReentrantLock保证单一线程执行 ReentrantLock保证了只有一个线程可以执行临界区代码: 临界区代码:任何时候只有1个线程可以执行的代码块. 临界区指的是一个访问共用资源(例如:共 ...
- 廖雪峰Java11多线程编程-2线程同步-3死锁
1.线程锁可以嵌套 在多线程编程中,要执行synchronized块: 必须首先获得指定对象的锁 Java的线程锁是可重入的锁.对同一个对象,同一个线程,可以多次获取他的锁,即同一把锁可以嵌套.如以下 ...
随机推荐
- SPSS缺失值得分析处理
SPSS缺失值得分析处理 在资料收集的过程中,由于各种原因可能导致数据收集不全,就会产生缺失值,且这种情况往往无法避免.如果缺失值处理不当,就会导致分析结果精度降低,出现偏倚甚至是错误的理论,因此缺失 ...
- windows中无法访问共享问题
http://jingyan.baidu.com/article/456c463b66d9320a5831448b.html 很多情况下我们遇到我们设置的共享没有密码别人无法访问,为此为大家推荐几步操 ...
- Python3 From Zero——{最初的意识:003~数字、日期、时间}
一.对数值进行取整:round(value,ndigits) >>> round(15.5,-1) #可以取负数 20.0 >>> round(15.5,0) #当 ...
- docker集群管理之kubernetes
一.简介 kubernetes又叫做k8s,是Google开发的一款开源的docker集群管理工具,在这里对它的“发家史”,我不做过多的阐述,有时间大家可以自己去百度一下: 下面我要讲的就是容易混淆的 ...
- MYSQL查询查找重复的电子邮箱
编写一个 SQL 查询,查找 Person 表中所有重复的电子邮箱. 示例: +----+---------+| Id | Email |+----+---------+| 1 | a@b.com | ...
- mock.js使用教程
转载自:https://blog.csdn.net/qq_42205731/article/details/81705350 cdn引入文件 :<script src="http:// ...
- Dubbo的服务请求失败怎么处理
dubbo启动时默认有重试机制和超时机制. 超时机制的规则是如果在一定的时间内,provider没有返回,则认为本次调用失败, 重试机制在出现调用失败时,会再次调用.如果在配置的调用次数内都失败,则认 ...
- Nginx配置两份日志记录
nginx配置 版本-1.4.4 --- access_log /alidata/log/nginx/access/wordpress1.log ; access_log /alidata/log/n ...
- php 垃圾回收机制 转载
PHP的基本GC概念PHP语言同其他语言一样,具有垃圾回收机制.那么今天我们要为大家讲解的内容就是关于PHP垃圾回收机制的相关问题.希望对大家有所帮助.PHP strtotime应用经验之谈PHP m ...
- JQUERY(入口函数 选择器)
入口函数 $(document).ready(function(){ });可以简写为$(function(){}) 选择器 基本选择器 元素选择器 $("p") 所有 & ...