无锁

一、概述

无锁是处理并发的一种乐观策略,它会假设对资源的访问是没有冲突的。既然没有冲突自然不需要等待,所以所有的线程都可以在不停顿的状态下执行。那遇到冲突怎么办?接下来请看,无锁绝招“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并发程序设计(七)乐天派:无锁的更多相关文章

  1. 【实战Java高并发程序设计 2】无锁的对象引用:AtomicReference

    AtomicReference和AtomicInteger非常类似,不同之处就在于AtomicInteger是对整数的封装,而AtomicReference则对应普通的对象引用.也就是它可以保证你在修 ...

  2. Java并发程序设计(十三)锁的性能优化

    锁的性能优化 一.优化注意事件 一)减少锁的持有时间 只在必要时进行同步,能明显减少锁的持有时间. 二)锁的细化 缺陷:当系统需要全局锁时,其消耗的资源会比较多. 三)锁的分离 比如读写分离锁 四)锁 ...

  3. Java并发基础:了解无锁CAS就从源码分析

    https://segmentfault.com/a/1190000015881923

  4. Java并发程序设计(一) 基础概念

    Java并发程序设计(一) 基础概念 一.必须知道的几个概念 一)同步(Synchronous)和异步(Asynchronous) 同步:同步方法调用一旦开始,调用者必须等到方法调用返回后,才能继续后 ...

  5. Java并发编程实战 03互斥锁 解决原子性问题

    文章系列 Java并发编程实战 01并发编程的Bug源头 Java并发编程实战 02Java如何解决可见性和有序性问题 摘要 在上一篇文章02Java如何解决可见性和有序性问题当中,我们解决了可见性和 ...

  6. java并发笔记之synchronized 偏向锁 轻量级锁 重量级锁证明

    警告⚠️:本文耗时很长,先做好心理准备 本篇将从hotspot源码(64 bits)入手,通过分析java对象头引申出锁的状态:本文采用大量实例及分析,请耐心看完,谢谢   先来看一下hotspot的 ...

  7. Java并发编程:synchronized和锁优化

    1. 使用方法 synchronized 是 java 中最常用的保证线程安全的方式,synchronized 的作用主要有三方面: 确保线程互斥的访问代码块,同一时刻只有一个方法可以进入到临界区 保 ...

  8. java并发笔记之证明 synchronized锁 是否真实存在

    警告⚠️:本文耗时很长,先做好心理准备 证明:偏向锁.轻量级锁.重量级锁真实存在 由[java并发笔记之java线程模型]链接: https://www.cnblogs.com/yuhangwang/ ...

  9. 【Java并发系列04】线程锁synchronized和Lock和volatile和Condition

    img { border: solid 1px } 一.前言 多线程怎么防止竞争资源,即防止对同一资源进行并发操作,那就是使用加锁机制.这是Java并发编程中必须要理解的一个知识点.其实使用起来还是比 ...

随机推荐

  1. ImageNet Classification with Deep Convolutional Neural Networks(译文)转载

    ImageNet Classification with Deep Convolutional Neural Networks Alex Krizhevsky, Ilya Sutskever, Geo ...

  2. Linux电源管理【转】

    转自:http://www.cnblogs.com/sky-zhang/archive/2012/06/05/2536807.html PM notifier机制: 应用场景: There are s ...

  3. mac 报错Root chmod operation not permitted on file

    系统:mac os 10.14.1 重启电脑 mac用户在升级系统之后,电脑启用了SIP(System Integrity Protection),增加了rootless机制,导致即使在root权限下 ...

  4. tomcat配置文件context.xml和server.xml分析

    在tomcat 5.5之前Context体现在/conf/server.xml中的Host里的<Context>元素,它由Context接口定义.每个<Context元素代表了运行在 ...

  5. centos重启报错Umounting file systems:umount:/opt:device is busy

    系统重启报错: Umounting file systems:umount:/opt:device is busy 只能硬关机,回想一下最近刚安装了nod32 for linux x64的杀毒软件,开 ...

  6. curl, wget常用选项

    使用指定的http代理,配合md5sum 对于检查源站与cdn节点资源是否一致很有效 curl -o a.jpg -x http://pbcdn.xximg1.com/v6/global2015/im ...

  7. 对比synchronized与java.util.concurrent.locks.Lock 的异同

    主要区别 1.Lock能完成几乎所有synchronized的功能,并有一些后者不具备的功能,如公平锁.等待可中断.锁绑定多个条件等: 2.synchronized 是Java 语言层面的,是内置的关 ...

  8. MyCP(课下作业,必做)

    作业要求 编写MyCP.java 实现类似Linux下cp XXX1 XXX2的功能,要求MyCP支持两个参数: java MyCP -tx XXX1.txt XXX2.bin 用来把文本文件(内容为 ...

  9. VM 安装 linux Enterprise_R5_U4_Server_I386_DVD教程图解

    ocp 学习笔记 20161126--------linux 笔记整理 一:安装linux系统环境: 1:linux 系统安装包下载路径:链接:链接: https://pan.baidu.com/s/ ...

  10. springMVC3学习--ModelAndView对象(转)

    原文链接:springMVC3学习(二)--ModelAndView对象 当控制器处理完请求时,通常会将包含视图名称或视图对象以及一些模型属性的ModelAndView对象返回到DispatcherS ...