Java多线程系列九——Atomic类
参考资料:https://fangjian0423.github.io/2016/03/16/java-AtomicInteger-analysis/
http://www.cnblogs.com/549294286/p/3766717.html
最近面试遇到一道编程题,要求两个线程交替打印[0,100]的数字,其中一个只打印奇数,另一个只打印偶数,并且给出特别明显的提示AtomicInteger,当时我在想简直是送分题啊,但事后回想由于手写又没有记得所有API,很多地方不完美,所以面试官最后让我解释一下,回来再用IDE写一遍就顺畅多了,解题思路:
- 定义thread0输出奇数,thread1输出偶数
- thread0执行时,若当前值为偶数则进入waiting状态并焕醒thread1
- thread1执行时,若当前值为奇数则进入waiting状态并焕醒thread0
- 循环执行上两步直到当前值达到100
import java.util.concurrent.atomic.AtomicInteger; /**
* @Description: 测试AtomicInteger*/
public class AtomicIntegerTest {
private static AtomicInteger num = new AtomicInteger(0); public static void main(String[] args) {
MyThead thread0 = new MyThead(1);
MyThead thread1 = new MyThead(0);
thread0.start();
thread1.start();
} public static class MyThead extends Thread { private int v; public MyThead(int v) {
this.v = v;
} @Override
public void run() {
synchronized (num) {
while (num.get() < 100) {
if (v == 1) {
if (num.get() % 2 == 0) {
try {
num.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
} else {
System.out.println(num.incrementAndGet());
num.notifyAll();
}
} else if (v == 0) {
if (num.get() % 2 == 1) {
try {
num.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
} else {
System.out.println(num.incrementAndGet());
num.notifyAll();
}
}
}
}
}
}
}
从AtomicInteger类源码可以看到,它定义了一个volatile的变量value用于存储值,而所有的操作都借助Unsafe类的操作来完成,Unsafe类的许多操作为CAS,可以理解为自带乐观锁,乐观锁就会存在ABA问题,但由于AtomicInteger保存的是int元素,在上题中背景下这个问题几乎可以忽略,故可认为它是线程安全的(若是用AtomicReference,ABA问题就可能带来致命问题,AtomicStampedReference类可用来解决这个问题)。
Java多线程系列九——Atomic类的更多相关文章
- java多线程系列(九)---ArrayBlockingQueue源码分析
java多线程系列(九)---ArrayBlockingQueue源码分析 目录 认识cpu.核心与线程 java多线程系列(一)之java多线程技能 java多线程系列(二)之对象变量的并发访问 j ...
- Java多线程系列五——列表类
参考资料: http://xxgblog.com/2016/04/02/traverse-list-thread-safe/ 一些列表类及其特性 类 线程安全 Iterator 特性 说明 Vect ...
- Java多线程系列二——Thread类的方法
Thread实现Runnable接口并实现了大量实用的方法 public static native void yield(); 此方法释放CPU,但并不释放已获得的锁,其它就绪的线程将可能得到执行机 ...
- (Java多线程系列九)线程池
线程池 1.什么是线程池 线程池是指在初始化一个多线程应用程序过程中创建一个线程集合,然后在需要执行新的任务时重用这些线程而不是新建一个线程.线程池中线程的数量通常取决于可用内存数量和应用程序的需求. ...
- java多线程系列5 atomic简介
先看一个例子,AtomicInteger 实现的线程安全的累加器 public class AtomicIntTest { public static void main(String[] args) ...
- java多线程系列 目录
Java多线程系列1 线程创建以及状态切换 Java多线程系列2 线程常见方法介绍 Java多线程系列3 synchronized 关键词 Java多线程系列4 线程交互(wait和 ...
- java多线程系列(五)---synchronized ReentrantLock volatile Atomic 原理分析
java多线程系列(五)---synchronized ReentrantLock volatile Atomic 原理分析 前言:如有不正确的地方,还望指正. 目录 认识cpu.核心与线程 java ...
- Java多线程系列--“JUC锁”03之 公平锁(一)
概要 本章对“公平锁”的获取锁机制进行介绍(本文的公平锁指的是互斥锁的公平锁),内容包括:基本概念ReentrantLock数据结构参考代码获取公平锁(基于JDK1.7.0_40)一. tryAcqu ...
- Java多线程系列--“JUC锁”04之 公平锁(二)
概要 前面一章,我们学习了“公平锁”获取锁的详细流程:这里,我们再来看看“公平锁”释放锁的过程.内容包括:参考代码释放公平锁(基于JDK1.7.0_40) “公平锁”的获取过程请参考“Java多线程系 ...
随机推荐
- java遍历文件夹及所有子文件
以前写代码循环文件夹和子文件时,总是自己写递归访问,今天研究lucene时,发现JDK给我们已经提供了访问遍历的方法,上代码: String str = "C:\\Users\\LLY\\D ...
- linux命令1——基础
Rm 删除命令 Rm [选项][文件] 删除一个文件或者目录 选项:r 递归的删除文件夹及其子文件,f 忽略不存在的文件(不提示) (2)rm删除目录下所有文件,但不删除目录 >>rm - ...
- 转载:用vector保存对象时保存指针的优点, 以及reserve的使用
#include <vector> #include <stdio.h> class A { public: A() { printf("A()/n"); ...
- 学习日常笔记<day14>自定义标签
1自定义标签 1.1第一个自定义标签开发步骤 1)编写一个普通的java类,继承SimpleTagSupport类,叫标签处理器类 /** * 标签处理器类 * @author APPle * 1)继 ...
- 纯Java Web项目下的Session共享方案收集(待实践)
1.使用filter方法存储 这种方法比较推荐,因为它的服务器使用范围比较多,不仅限于tomcat ,而且实现的原理比较简单容易控制. 可以使用memcached-session-filter 官方网 ...
- ubuntu16.04LTS安装软件
1.安装chrome 下载源加入到系统的源列表 sudo wget http://www.linuxidc.com/files/repo/google-chrome.list -P /etc/apt/ ...
- B-Tree 索引和 Hash 索引的对照
对于 B-tree 和 hash 数据结构的理解可以有助于预測不同存储引擎下使用不同索引的查询性能的差异.尤其是那些同意你选择 B-tree 或者 hash 索引的内存存储引擎. B-Tree 索引的 ...
- angular $resource 的 get请求 和 post请求
1.语法: $resource(url,[paramDefaults],[actions],options); 详解: (1)url:一个参数化的url模板 (2)paramDefaults:url参 ...
- DosBox 报错 this program requires dosxnt.exe to be in your path
也就是少了dosxnt.exe文件,能够上网搜索下载,把dosxnt 拷贝到你挂截文件夹下就能够执行 Dosxnt文件下载
- 【Mongodb教程 第四课 】MongoDB 创建集合
reateCollection() 方法 MongoDB db.createCollection(name, options) 是用来创建集合. 语法: 基本的 createCollection() ...