原子更新基本类型

原子更新数组

原子更新抽象类型

原子更新字段

原子更新基本类型:

 
package com.roocon.thread.t8;

import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicIntegerArray; public class Sequence {
private AtomicInteger value = new AtomicInteger(0);
private int [] s = {2,1,4,6};
AtomicIntegerArray a = new AtomicIntegerArray(s); public int getNext(){
a.getAndIncrement(2);//给下标为2的元素加1
a.getAndAdd(2, 10);//获取下标为2的元素,并且加10
for (int i=0; i < a.length(); i++){
System.out.println(a.get(i));
}
return value.getAndIncrement();
} public static void main(String[] args) {
Sequence sequence = new Sequence();
new Thread(new Runnable() {
@Override
public void run() {
while (true){
System.out.println(Thread.currentThread().getName()+" "+sequence.getNext());
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
while (true){
System.out.println(Thread.currentThread().getName()+" "+sequence.getNext());
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
while (true){
System.out.println(Thread.currentThread().getName()+" "+sequence.getNext());
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
}
}
 

运行结果:

 
Thread-0 0
Thread-1 1
Thread-2 2
Thread-0 3
Thread-1 4
Thread-2 5
...
 
 
package com.roocon.thread.t8;

import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicIntegerArray;
import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
import java.util.concurrent.atomic.AtomicReference; public class Sequence {
private AtomicInteger value = new AtomicInteger(0);
AtomicReference<User> user = new AtomicReference<>(); //对user的set和get执行原子操作
AtomicIntegerFieldUpdater<User> old = AtomicIntegerFieldUpdater.newUpdater(User.class, "old"); public int getNext(){
User user = new User();
System.out.println(old.getAndIncrement(user));
System.out.println(old.getAndIncrement(user));
System.out.println(old.getAndIncrement(user));
return value.getAndIncrement();
} public static void main(String[] args) {
Sequence sequence = new Sequence();
new Thread(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+" "+sequence.getNext());
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
}
}
 

运行结果:

0
1
2
Thread-0 0

对CAS的源码理解:--初步理解

在AtomicInteger中有这样一段源码:

 
public final int getAndUpdate(IntUnaryOperator updateFunction) {
int prev, next;
do {
prev = get();
next = updateFunction.applyAsInt(prev);
} while (!compareAndSet(prev, next));
return prev;
}
public final boolean compareAndSet(int expect, int update) {
return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
}
 
 

其中,compareAndSwap就是CAS的缩写。如果prev和next不相等,则返回true。否则,返回false。最终是通过unsafe来实现的。

以上代码表示,如果compareAndSet返回true,则while条件为false,退出循环,返回prev值。如果compareAndSet返回false,则while为true,继续执行循环体,重新获取prev的值,重新获取更新值,直到返回的compareAndSet值为true。

演示源码大致步骤如下:

 Object prev = get(); //
next = prev + 1;
boolean flag = cas(prev, next);
if (flag) {
return prev;
}else {
go to 1
} Object pre

参考资料:

《java并发编程与实战》龙果学院

Java并发编程原理与实战十三:JDK提供的原子类原理与使用的更多相关文章

  1. 并发编程学习笔记(4)----jdk5中提供的原子类及Lock使用及原理

    (1)jdk中原子类的使用: jdk5中提供了很多原子类,它会使变量的操作变成原子性的. 原子性:原子性指的是一个操作是不可中断的,即使是在多个线程一起操作的情况下,一个操作一旦开始,就不会被其他线程 ...

  2. JDK提供的原子类原理与使用

    原子更新基本类型 原子更新数组 原子更新抽象类型 原子更新字段 原子更新基本类型: package com.roocon.thread.t8; import java.util.concurrent. ...

  3. 转:【Java并发编程】之二十三:并发新特性—信号量Semaphore(含代码)

    载请注明出处:http://blog.csdn.net/ns_code/article/details/17524153 在操作系统中,信号量是个很重要的概念,它在控制进程间的协作方面有着非常重要的作 ...

  4. JDK提供的原子类和AbstractQueuedSynchronizer(AQS)

    大致分成: 1.原子更新基本类型 2.原子更新数组 3.原子更新抽象类型 4.原子更新字段 import java.util.concurrent.atomic.AtomicInteger; impo ...

  5. Java并发编程原理与实战二十:线程安全性问题简单总结

    一.出现线程安全性问题的条件 •在多线程的环境下 •必须有共享资源 •对共享资源进行非原子性操作   二.解决线程安全性问题的途径 •synchronized (偏向锁,轻量级锁,重量级锁) •vol ...

  6. Java并发编程原理与实战三十三:同步容器与并发容器

    1.什么叫容器? ----->数组,对象,集合等等都是容器.   2.什么叫同步容器? ----->Vector,ArrayList,HashMap等等.   3.在多线程环境下,为什么不 ...

  7. Java并发编程原理与实战三十一:Future&FutureTask 浅析

    一.Futrue模式有什么用?------>正所谓技术来源与生活,这里举个栗子.在家里,我们都有煮菜的经验.(如果没有的话,你们还怎样来泡女朋友呢?你懂得).现在女票要你煮四菜一汤,这汤是鸡汤, ...

  8. Java并发编程原理与实战二十五:ThreadLocal线程局部变量的使用和原理

    1.什么是ThreadLocal ThreadLocal顾名思义是线程局部变量.这种变量和普通的变量不同,这种变量在每个线程中通过get和set方法访问, 每个线程有自己独立的变量副本.线程局部变量不 ...

  9. Java并发编程原理与实战十:单例问题与线程安全性深入解析

    单例模式我想这个设计模式大家都很熟悉,如果不熟悉的可以看我写的设计模式系列然后再来看本文.单例模式通常可以分为:饿汉式和懒汉式,那么分别和线程安全是否有关呢? 一.饿汉式 先看代码: package ...

随机推荐

  1. APP案例分析之华为浏览器

    第一部分  对华为浏览器的调研,评测 1.对华为浏览器的第一次上手体验 我会使用华为浏览器呢,是因为我买的手机是华为nova,该浏览器也是手机里面预装的.刚开始用的时候也没太注意,感觉跟以前用的其他浏 ...

  2. Swift-懒加载使用

    //    懒加载 lazy var tableView : UITableView = {         let tempTableView = UITableView()         ret ...

  3. 简单Profibus/DP实验系统的组建

    转自:http://www.dndev.com/Profibus/profibustr/system_4.html 引言: 为了让更多刚接触到Profibus系统的朋友能对Profibus的网络架构及 ...

  4. js访问对象属性的两种方法

    var obj={name:'fuuf',age:19} 第一种,用.访问 obj.name 第二种 用[]访问 obj['name']  //此时name是字符串,要加引号 注意事项 使用第二种方法 ...

  5. jQuery扩展插件

    jQuery有多好用,大家有目共睹的,但是有时候不是每个功能都是万能的,有时候我们需要实现自己的功能,jQuery提供了很好的拓展功能,我们可以去拓展插件,更好的利用jQuery 查看官网,可知,有两 ...

  6. call()方法和apply()方法

    最近又遇到了JacvaScript中的call()方法和apply()方法,而在某些时候这两个方法还确实是十分重要的,那么就让我总结这两个方法的使用和区别吧. 1. 每个函数都包含两个非继承而来的方法 ...

  7. [转帖]升级 Ubuntu,解决登录时提示有软件包可以更新的问题

    升级 Ubuntu,解决登录时提示有软件包可以更新的问题 2017年12月05日 11:58:17 阅读数:2953更多 个人分类: ubuntu Connecting to ... Connecti ...

  8. rhel和centos7下更改网卡名称ens33为eth0

    Linux使用小Tips 整理些Linux些常遇到的问题. 修改网卡ens33为eth0 在使用RHEL和Centos7,发现网卡名称变成了EnoX,挺不习惯.现更改回旧名称eth0看着顺眼. 备份/ ...

  9. P4254 [JSOI2008]Blue Mary开公司

    题面 这道题的意思就是给出若干个一次函数,当\(x=x_0\)时,最大的\(y\)为多少 这种题可以用李超线段树来处理 什么是李超线段树呢? 李超线段树存储的是在区间上方暴露最多的直线标号,为了便于描 ...

  10. Netty基础系列(3) --彻底理解NIO

    前言 上一节中我们提到了同步异步与阻塞非阻塞的区别,知道了同步并不等于阻塞.而本节的主角NIO是一种同步非阻塞的I/O模型,并且是I/O多路复用模型.NIO在java中被称为 New I/O.它并不能 ...