Java并发程序设计(七)乐天派:无锁
无锁
一、概述
无锁是处理并发的一种乐观策略,它会假设对资源的访问是没有冲突的。既然没有冲突自然不需要等待,所以所有的线程都可以在不停顿的状态下执行。那遇到冲突怎么办?接下来请看,无锁绝招“CAS”即比较交换术。
二、CAS原理
CAS即Compare and swap.其算法过程是这样的:它有三个参数:
1.V表示要更新的变量
2.E表示期望值
3.N表示新值
仅当V等于E时,才会将V设为N。如果V和N不同,则说明有其他线程做了更新,则该线程什么都不做。当多个线程同时使用CAS进行变量操作时,只有一个会更新成功,其余都会失败。失败的线程不会被挂起,而是进行重试。
三、无锁的线程安全整数:AtomicInteger
AtomicInteger主要方法如下(对于其他无锁线程安全类,其方法类似):
public final int get() //取得当前值
public final void set(int newValue) //设置当前值
public final int getAndset(int newValue) //设置新值返回旧值
public final boolean compareAndSet(int except,int u) //如果当前值为except则设为u
public final int getAndIncrement() //当前值加1返回旧值
public final int getAndDecrement()
public final int getAndAdd(int delta)
public final int incrementAndGet()
public final int decrementAndGet()
public final int addAndGet()
就AtomicInteger核心字段:
private volatile int value; //代表AtomicInteger当前的值
private static final long valueOffset; //value字段的偏移量
AtomicInteger的使用示例:
public class AutomicIntegerDemo {
static AtomicInteger i=new AtomicInteger();
public static class addThread implements Runnable{
@Override
public void run() {
for(int j=0;j<1000;j++){
i.incrementAndGet();
}
}
}
public static void main(String[] args) throws InterruptedException {
Thread[] ts=new Thread[10];
for(int j=0;j<10;j++){
ts[j]=new Thread(new addThread());
}
for(int j=0;j<10;j++) ts[j].start();
for (int j=0;j<10;j++) ts[j].join();
System.out.println(i);
}
}
相比使用锁,使用无锁会有更好的性能。
四、CAS算法逻辑上瑕疵及解决办法:AtomicStampedReference
CAS算法逻辑上的瑕疵:当你获得对象当前数据后,在准备修改为新值前,对象的值被其他对象连续修改了两次,而经过这两次修改后,对象的值又恢复到旧值。这样,当前线程就无法判断该值是否被修改过。也就是说你修改的对象数值没有过程状态信息。
AtomicStampedReference内部不仅维护了对象值还维护了一个状态值。
五、无锁数组
当前可用的原子数组有:AtomicIntegerArray,AtomicLongArray和AtomicReferenceArray
public class AtomicIntegerArrayDemo {
static AtomicIntegerArray array=new AtomicIntegerArray(10);
public static class addThread implements Runnable{
@Override
public void run() {
for (int j=0;j<1000;j++){
array.getAndIncrement(j%array.length());
}
}
}
public static void main(String[] args) throws InterruptedException {
Thread[] ts=new Thread[10];
for (int j=0;j<10;j++){
ts[j]=new Thread(new addThread());
}
for (int j=0;j<10;j++) ts[j].start();
for (int j=0;j<10;j++) ts[j].join();
System.out.println(array);
}
}
六、让普通变量也享受原子操作:AtomicIntegerFieldUpdater
public class AtomicIntegerFieldUpdaterDemon {
public static class Candidate{
int id;
volatile int score;
}
public final static AtomicIntegerFieldUpdater<Candidate> scoreUpdater=
AtomicIntegerFieldUpdater.newUpdater(Candidate.class,"score");
public static AtomicInteger checkScore=new AtomicInteger(0); //用于检测
public static void main(String[] args) throws InterruptedException {
final Candidate candidate=new Candidate();
Thread[] threads=new Thread[1000];
for (int i=0;i<1000;i++){
threads[i]=new Thread(){
public void run(){
if (Math.random()>0.4){
scoreUpdater.incrementAndGet(candidate);
checkScore.incrementAndGet();
}
}
};
threads[i].start();
}
for (int i=0;i<1000;i++) threads[i].join();
System.out.println("score="+candidate.score);
System.out.println("checkScore="+checkScore);
}
}
注意事项:
1.Updater只能修改可见范围内的变量。
2.变量必须是volatile
3.变量不能是static的
Java并发程序设计(七)乐天派:无锁的更多相关文章
- 【实战Java高并发程序设计 2】无锁的对象引用:AtomicReference
AtomicReference和AtomicInteger非常类似,不同之处就在于AtomicInteger是对整数的封装,而AtomicReference则对应普通的对象引用.也就是它可以保证你在修 ...
- Java并发程序设计(十三)锁的性能优化
锁的性能优化 一.优化注意事件 一)减少锁的持有时间 只在必要时进行同步,能明显减少锁的持有时间. 二)锁的细化 缺陷:当系统需要全局锁时,其消耗的资源会比较多. 三)锁的分离 比如读写分离锁 四)锁 ...
- Java并发基础:了解无锁CAS就从源码分析
https://segmentfault.com/a/1190000015881923
- Java并发程序设计(一) 基础概念
Java并发程序设计(一) 基础概念 一.必须知道的几个概念 一)同步(Synchronous)和异步(Asynchronous) 同步:同步方法调用一旦开始,调用者必须等到方法调用返回后,才能继续后 ...
- Java并发编程实战 03互斥锁 解决原子性问题
文章系列 Java并发编程实战 01并发编程的Bug源头 Java并发编程实战 02Java如何解决可见性和有序性问题 摘要 在上一篇文章02Java如何解决可见性和有序性问题当中,我们解决了可见性和 ...
- java并发笔记之synchronized 偏向锁 轻量级锁 重量级锁证明
警告⚠️:本文耗时很长,先做好心理准备 本篇将从hotspot源码(64 bits)入手,通过分析java对象头引申出锁的状态:本文采用大量实例及分析,请耐心看完,谢谢 先来看一下hotspot的 ...
- Java并发编程:synchronized和锁优化
1. 使用方法 synchronized 是 java 中最常用的保证线程安全的方式,synchronized 的作用主要有三方面: 确保线程互斥的访问代码块,同一时刻只有一个方法可以进入到临界区 保 ...
- java并发笔记之证明 synchronized锁 是否真实存在
警告⚠️:本文耗时很长,先做好心理准备 证明:偏向锁.轻量级锁.重量级锁真实存在 由[java并发笔记之java线程模型]链接: https://www.cnblogs.com/yuhangwang/ ...
- 【Java并发系列04】线程锁synchronized和Lock和volatile和Condition
img { border: solid 1px } 一.前言 多线程怎么防止竞争资源,即防止对同一资源进行并发操作,那就是使用加锁机制.这是Java并发编程中必须要理解的一个知识点.其实使用起来还是比 ...
随机推荐
- ImageNet Classification with Deep Convolutional Neural Networks(译文)转载
ImageNet Classification with Deep Convolutional Neural Networks Alex Krizhevsky, Ilya Sutskever, Geo ...
- Linux电源管理【转】
转自:http://www.cnblogs.com/sky-zhang/archive/2012/06/05/2536807.html PM notifier机制: 应用场景: There are s ...
- mac 报错Root chmod operation not permitted on file
系统:mac os 10.14.1 重启电脑 mac用户在升级系统之后,电脑启用了SIP(System Integrity Protection),增加了rootless机制,导致即使在root权限下 ...
- tomcat配置文件context.xml和server.xml分析
在tomcat 5.5之前Context体现在/conf/server.xml中的Host里的<Context>元素,它由Context接口定义.每个<Context元素代表了运行在 ...
- centos重启报错Umounting file systems:umount:/opt:device is busy
系统重启报错: Umounting file systems:umount:/opt:device is busy 只能硬关机,回想一下最近刚安装了nod32 for linux x64的杀毒软件,开 ...
- curl, wget常用选项
使用指定的http代理,配合md5sum 对于检查源站与cdn节点资源是否一致很有效 curl -o a.jpg -x http://pbcdn.xximg1.com/v6/global2015/im ...
- 对比synchronized与java.util.concurrent.locks.Lock 的异同
主要区别 1.Lock能完成几乎所有synchronized的功能,并有一些后者不具备的功能,如公平锁.等待可中断.锁绑定多个条件等: 2.synchronized 是Java 语言层面的,是内置的关 ...
- MyCP(课下作业,必做)
作业要求 编写MyCP.java 实现类似Linux下cp XXX1 XXX2的功能,要求MyCP支持两个参数: java MyCP -tx XXX1.txt XXX2.bin 用来把文本文件(内容为 ...
- VM 安装 linux Enterprise_R5_U4_Server_I386_DVD教程图解
ocp 学习笔记 20161126--------linux 笔记整理 一:安装linux系统环境: 1:linux 系统安装包下载路径:链接:链接: https://pan.baidu.com/s/ ...
- springMVC3学习--ModelAndView对象(转)
原文链接:springMVC3学习(二)--ModelAndView对象 当控制器处理完请求时,通常会将包含视图名称或视图对象以及一些模型属性的ModelAndView对象返回到DispatcherS ...