java引用的竞争条件
原子整数、long、boolean等用于对相应类型进行任何原子更新,因为当我们对它们执行任何操作时,可能会出现竞争条件,例如++。但是,在参考文献中可能存在这种竞争条件的情况有哪些不同 致以最诚挚的问候,java引用的竞争条件,java,multithreading,reference,atomicreference,Java,Multithreading,Reference,Atomicreference,原子整数、long、boolean等用于对相应类型进行任何原子更新,因为当我们对它们执行任何操作时,可能会出现竞争条件,例如++。但是,在参考文献中可能存在这种竞争条件的情况有哪些不同 致以最诚挚的问候, Keshav像++这样的操作受到竞争条件的影响,因为它们涉及多个离散操作(获取、增量、存储) 设置参考(a=b)是一项单一操作,因此不受竞争条件的约束 引用类型(a.someMethod())上的操作可以做任何他们想做的事情,可能受竞争条件的约束,也可能不受竞争条件的约束。像++这样的操作受竞
Keshav像
++
这样的操作受到竞争条件的影响,因为它们涉及多个离散操作(获取、增量、存储)
设置参考(a=b
)是一项单一操作,因此不受竞争条件的约束
引用类型(
a.someMethod()
)上的操作可以做任何他们想做的事情,可能受竞争条件的约束,也可能不受竞争条件的约束。像++
这样的操作受竞争条件的约束,因为它们涉及多个离散操作(获取、增量、存储)
设置参考(a=b
)是一项单一操作,因此不受竞争条件的约束
引用类型(
a.someMethod()
)上的操作可以做任何他们想做的事情,可能受竞争条件的约束,也可能不受竞争条件的约束。AFAIK引用不受竞争条件的约束,因为JVM保证引用更新是一个原子操作(不同于例如更新长的,其中较低和较高的4个字节分两个不同的步骤进行更新)。正如SLaks所指出的,唯一的关键情况是compareAndSet
,它本质上不是原子的。这很少用于本机引用,但当需要更新两个(或更多)时,这是一个与AtomicReference
相关的惯用用法Java并发在实践中,第15.3.1节为此发布了一个示例,使用AtomicReference
在一个原子操作中更新两个变量(存储在一个简单类中)
除了接口的一致性之外,AtomicReference
存在的主要原因是可见性和安全发布。从这个意义上说,原子变量是“更好的易失性”
.AFAIK引用不受竞争条件的约束,因为JVM保证引用更新是一个原子操作(不同于例如更新long
,其中较低和较高的4个字节在两个不同的步骤中更新)。正如SLaks所指出的,唯一的关键情况是compareAndSet
,它本质上不是原子的。这很少用于本机引用,但当需要更新两个(或更多)时,这是一个与AtomicReference
相关的惯用用法Java并发在实践中,第15.3.1节为此发布了一个示例,使用AtomicReference
在一个原子操作中更新两个变量(存储在一个简单类中)
除了接口的一致性之外,原子引用存在的主要原因是可见性和安全发布。从这个意义上说,原子变量是一个“更好的易失性”出于学习目的,我使用原子引用编写了一个ConcurrentLinkQueue
package concurrent.AtomicE;
import java.util.concurrent.atomic.AtomicReference;
public class ConcurrentLinkQueue<V> {
private final AtomicReference<Node> firstNodePointer = new AtomicReference<Node>();
public void fastOffer(final V data){
final Node<V> newNode = new Node<V>(data,Thread.currentThread().getName());
System.out.println(newNode);
AtomicReference<Node> pointer = firstNodePointer;
for(;;){
if(pointer.get() == null){
if(pointer.compareAndSet(null,newNode)){
return;
}
}
pointer = pointer.get().getNext();
}
}
private static class Node<V>{
private AtomicReference<Node> next = new AtomicReference<Node>();
private volatile V data = null;
private String threadName = "";
Node(V data1,String threadName){
this.data = data1;
this.threadName = threadName;
}
@Override
public String toString() {
return "threadName=" + threadName +
", data=" + data;
}
private AtomicReference<Node> getNext() {
return next;
}
private void setNext(AtomicReference<Node> next) {
this.next = next;
}
private V getData() {
return data;
}
private void setData(V data) {
this.data = data;
}
}
package concurrent.atomies;
导入java.util.concurrent.AtomicReference;
公共类ConcurrentLinkQueue{
private final AtomicReference FirstNodePointInter=新的AtomicReference();
公开发售(最终V数据){
final Node newNode=新节点(数据,Thread.currentThread().getName());
System.out.println(newNode);
原子引用指针=第一节点指针;
对于(;;){
if(pointer.get()==null){
if(指针.比较数据集(null,新节点)){
回来
}
}
指针=指针.get().getNext();
}
}
私有静态类节点{
私有AtomicReference next=新的AtomicReference();
私有volatile V data=null;
私有字符串threadName=“”;
节点(V data1,字符串threadName){
这个.data=data1;
this.threadName=threadName;
}
@凌驾
公共字符串toString(){
返回“threadName=“+threadName+
“,data=“+数据;
}
私有原子引用getNext(){
下一步返回;
}
私有void setNext(原子引用next){
this.next=next;
}
private V getData(){
返回数据;
}
私有void setData(V数据){
这个数据=数据;
}
}
出于学习目的,我使用AtomicReference编写了一个ConcurrentLinkQueue
package concurrent.AtomicE;
import java.util.concurrent.atomic.AtomicReference;
public class ConcurrentLinkQueue<V> {
private final AtomicReference<Node> firstNodePointer = new AtomicReference<Node>();
public void fastOffer(final V data){
final Node<V> newNode = new Node<V>(data,Thread.currentThread().getName());
System.out.println(newNode);
AtomicReference<Node> pointer = firstNodePointer;
for(;;){
if(pointer.get() == null){
if(pointer.compareAndSet(null,newNode)){
return;
}
}
pointer = pointer.get().getNext();
}
}
private static class Node<V>{
private AtomicReference<Node> next = new AtomicReference<Node>();
private volatile V data = null;
private String threadName = "";
Node(V data1,String threadName){
this.data = data1;
this.threadName = threadName;
}
@Override
public String toString() {
return "threadName=" + threadName +
", data=" + data;
}
private AtomicReference<Node> getNext() {
return next;
}
private void setNext(AtomicReference<Node> next) {
this.next = next;
}
private V getData() {
return data;
}
private void setData(V data) {
this.data = data;
}
}
package concurrent.atomies;
导入java.util.concurrent.AtomicReference;
公共类ConcurrentLinkQueue{
private final AtomicReference FirstNodePointInter=新的AtomicReference();
公开发售(最终V数据){
final Node newNode=新节点(数据,Thread.currentThread().getName());
System.out.println(newNode);
原子引用指针=第一节点指针;
对于(;;){
if(pointer.get()==null){
if(指针.比较数据集(null,新节点)){
回来
}
}
指针=指针.get().getNext();
}
}
私有静态类节点{
私有AtomicReference next=新的AtomicReference();
私有volatile V data=null;
私有字符串threadName=“”;
节点(V data1,字符串threadName){
这个.data=data1;
this.threadName=threadName;
}
@凌驾
公共字符串toString(){
返回“threadName=“+threadName+
“,data=“+数据;
}
私有原子引用getNext(){
下一步返回;
}
私有void setNext(原子引用next){
this.next=next;
}
private V getData(){
返回数据;
}
私有void setData(V数据){
这个数据=数据;
}
}
那我们为什么要上课AtomicReference@keshu:compareAndSet
受竞争条件的约束,因为它涉及两个操作。那么为什么我们有一个类AtomicReference@keshu:com