java compareandset 包_当set在Java中已经是原子时,为什么我们需要compareAndSet?

在多线程环境中有两个重要的概念。

原子

能见度

Volatile解决了可见性问题,但它不涉及原子性,例如:我++。在这里,i ++不是一个单一的机器指令,而是三个机器指令。

将值复制到注册

增加它

放回去

AtomicInteger,AtomicReference基于比较和交换指令。 CAS有三个操作数,一个操作的存储位置V,预期的旧值A和新的值B.CAS原子地将V更新为新的值B,但前提是V中的值与预期的旧值A匹配;否则它什么都不做。在任何一种情况下,它都返回当前V中的值。这由JVM在AtomicInteger,AtomicReference中使用,如果底层处理器不支持此功能,则它们将函数调用为compareAndSet(),然后JVM通过自旋锁实现它。

Set是原子的(它并不总是正确的)但是比较然后设置不是原子的。所以当你有这个要求时,例如当值为X然后只更改为Y所以要原子地执行此操作您需要这种基元,您可以使用AtomicInteger,AtomicReference的compareAndSet,例如atomicLong.compareAndSet(long expect, long update)

您实际上可以使用此原语来开发强大的数据结构,如并发堆栈。

import java.util.concurrent.atomic.AtomicReference;

public class MyConcurrentStack {

private AtomicReference head = new AtomicReference();

public MyConcurrentStack() {

}

public void push(T t) {

if (t == null) {

return;

}

Node n = new Node(t);

Node current;

do {

current = head.get();

n.setNext(current);

} while (!head.compareAndSet(current, n));

}

public T pop() {

Node currentHead = null;

Node futureHead = null;

do {

currentHead = head.get();

if (currentHead == null) {

return null;

}

futureHead = currentHead.next;

} while (!head.compareAndSet(currentHead, futureHead));

return currentHead.data;

}

/**

*

* @return null if no element present else return a element. it does not

* remove the element from the stack.

*/

public T peek() {

Node n = head.get();

if (n == null) {

return null;

} else {

return n.data;

}

}

public boolean isEmpty() {

if (head.get() == null) {

return true;

}

return false;

}

private static class Node {

private final T data;

private Node next;

private Node(T data) {

this.data = data;

}

private void setNext(Node next) {

this.next = next;

}

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值