Java并发编程之原子操作类
什么是原子操作类
当更新一个变量的时候,多出现数据争用的时候可能出现所意想不到的情况。这时的一般策略是使用synchronized解决,因为synchronized能够保证多个线程不会同时更新该变量。然而,从jdk 5之后,提供了粒度更细、量级更轻,并且在多核处理器具有高性能的原子操作类。因为原子操作类把竞争的范围缩小到单个变量上,这可以算是粒度最细的情况了。
原子操作类相当于泛化的volatile变量,能够支持原子读取-修改-写操作。比如AtomicInteger表示一个int类型的数值,提供了get和set方法,这些volatile类型的变量在读取与写入上有着相同的内存语义。原子操作类共有13个类,在java.util.concurrent.atomic包下,可以分为四种类型的原子更新类:原子更新基本类型、原子更新数组类型、原子更新引用和原子更新属性。
下面介绍这各种原子操作类
1 原子更新基本类型:使用原子方式更新基本类型
AtomicBoolean:原子更新布尔变量
AtomicInteger:原子更新整型变量
AtomicLong:原子更新长整型变量
2 原子更新数组:通过原子更新数组里的某个元素
AtomicIntegerArray:原子更新整型数组的某个元素
AtomicLongArray:原子更新长整型数组的某个元素
AtomicReferenceArray:原子更新引用类型数组的某个元素
3 原子更新引用类型:更新引用类型
AtomicReference:原子更新引用类型
AtomicReferenceFieldUpdater:原子更新引用类型里的字段
AtomicMarkableReference:原子更新带有标记位的引用类型
4 原子更新字段:原子更新某个类的某个字段
AtomicIntegerFieldUpdater:原子更新整型字段
AtomicLongFieldUpdater:原子更新长整型字段
AtomicStampedReference:原子更新带有版本号的引用类型
我们接下来会通过对AtomicInteger的讲解来深入认识原子操作类
在单线程环境下,执行num++等操作时不会出现问题,那么,在多线程环境下是否还是跟单线程环境下一样安全呢?我们通过一段代码进行模拟。
public class Demo {
private static int num = 0;
public static void add() {
num++;
}
public static void main(String[] args) {
Thread[] myThread = new Thread[10];
for(Thread thread : myThread) {
thread = new Thread() {
@Override
public void run() {
for(int i = 0;i < 1000;i++) {
add();
}
}
};
thread.start();
}
while (Thread.activeCount() > 1) {
Thread.yield();
}
System.out.println(num);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
我们进行三次测试,得出结果分别是
8400
8318
9856
在没有同步条件下,自增操作不具备原子性,在多线程环境下是不安全的。
既然我们上面的方法不安全,那该咋办呢,总不能坐以待毙吧?没事,我们有一件新武器,那就是AtomicInteger原子类型。把上面的代码改为使用AtomicInteger,让我们看看接下来会发生什么?
import java.util.concurrent.atomic.AtomicInteger;
public class Demo {
public static AtomicInteger num = new AtomicInteger(0);
public static void add() {
num.incrementAndGet();
}
public static void main(String[] args) {
Thread[] myThread = new Thread[10];
for(Thread thread : myThread) {
thread = new Thread() {
@Override
public void run() {
for(int i = 0;i < 1000;i++) {
add();
}
}
};
thread.start();
}
while (Thread.activeCount() > 1) {
Thread.yield();
}
System.out.println(num);
}
}
---------------------
Java并发编程之原子操作类的更多相关文章
- Java并发编程:Thread类的使用
Java并发编程:Thread类的使用 在前面2篇文章分别讲到了线程和进程的由来.以及如何在Java中怎么创建线程和进程.今天我们来学习一下Thread类,在学习Thread类之前,先介绍与线程相关知 ...
- 【转】Java并发编程:Thread类的使用
一.线程的状态 在正式学习Thread类中的具体方法之前,我们先来了解一下线程有哪些状态,这个将会有助于对Thread类中的方法的理解. 线程从创建到最终的消亡,要经历若干个状态.一般来说,线程包括以 ...
- 3、Java并发编程:Thread类的使用
Java并发编程:Thread类的使用 在前面2篇文章分别讲到了线程和进程的由来.以及如何在Java中怎么创建线程和进程.今天我们来学习一下Thread类,在学习Thread类之前,先介绍与线程相关知 ...
- java并发编程之原子操作
先来看一段简单的代码,稍微有点并发知识的都可以知道打印出结果必然是一个小于20000的值 package com.example.test.cas; import java.io.IOExceptio ...
- Java并发编程:Thread类的使用介绍
在学习Thread类之前,先介绍与线程相关知识:线程的几种状态.上下文切换,然后接着介绍Thread类中的方法的具体使用. 以下是本文的目录大纲: 一.线程的状态 二.上下文切换 三.Thread类中 ...
- Java并发编程:Thread类的使用(转载)
一:线程的状态: 在正式学习Thread类中的具体方法之前,我们先来了解一下线程有哪些状态,这个将会有助于后面对Thread类中的方法的理解. 线程从创建到最终的消亡,要经历若干个状态.一般来说,线程 ...
- java并发编程 - Exexctors 工具类
Executors 类提供了一系列静态工厂方法用于创建各种线程池. newFixedThreadPool 创建固定大小的线程池.每次提交一个任务就创建一个线程,直到线程达到线程池的最大大小.线程池的大 ...
- Java并发编程-总纲
Java 原生支持并发,基本的底层同步包括:synchronized,用来标示一个方法(普通,静态)或者一个块需要同步执行(某一时刻,只允许一个线程在执行代码块).volatile,用来标识一个变量是 ...
- java并发编程目录
java并发编程目录 Java多线程基础:进程和线程之由来 JAVA多线程实现的四种方式 Java并发编程:线程间协作的两种方式:wait.notify.notifyAll和Condition Jav ...
随机推荐
- angularJS 的双向数据绑定
input 里面的vale="变量名";加上ng-model="变量名";控制器的变量名会根据视图层的数据改变而改变,而渲染内容也会根据控制器里面的变量改变而改 ...
- Android Studio 1.5.1
Android Studio 1.5.1 December 3rd, 2015: For information on what's new in 1.5.1, see the release ann ...
- C#:template
ylbtech-C#: 1.返回顶部 2.返回顶部 3.返回顶部 4.返回顶部 5.返回顶部 6.返回顶部 作者:ylbtech出处:http://ylbtech.cnbl ...
- writing-mode属性
writing-mode属性 最初只是ie中的属性,只有ie支持,现在在css3中谷歌,火狐也开始支持. 所以使用的时候就需要记住两套不同的语法,ie的私有属性和css3的规范属性 如果只需要兼容到i ...
- A - Mike and Fax
Time Limit:1000MS Memory Limit:262144KB 64bit IO Format:%I64d & %I64u Description While ...
- C - Woodcutters
Time Limit:1000MS Memory Limit:262144KB 64bit IO Format:%I64d & %I64u Description Little ...
- 斯坦福CS231n—深度学习与计算机视觉----学习笔记 课时14&&15
课时14 卷积神经网络详解(上) CNN处理的是一些数据块,在这之间有很多层,一系列的层将输入数据变换为输出数据,所以完成操作的中间量不仅是NN时候讲的那些向量,而是立体结构,有宽,高和深度,在整个计 ...
- Swift里计数相关的小细节
Swift里对于字符串这些引入了index型,相对其他语言而言字符操作更安全了,但是问题就是一不注意搞错范围就会有各种离奇的bug. 在讲主题前,先说个小细节. Swift里非常严密的定义了一大堆字符 ...
- Codeforces - Gym102028 - 2018 Jiaozuo Regional Contest
http://codeforces.com/gym/102028 A. Xu Xiake in Henan Province 看起来像水题.乱搞一下,还真是. #include<bits/std ...
- poj1163 【记忆化搜索·水】
题意: 一个这样的三角形,他可以往下的左或者往下的右走.求一个在最后一行的最大. 思路: 额...就是搜一下..记录一下...肯定有重合的情况. code- //#include <bits/s ...