wordpress如何搬站,中文域名的价值,wordpress 无法置顶,做网站设计师的感想CAS 原子操作
CAS#xff08;Compare and Swap#xff09;是一种并发算法#xff0c;通常用于实现多线程环境下的同步操作#xff0c;特别是在并发编程中实现无锁算法。CAS操作涉及三个参数#xff1a;内存位置#xff08;V#xff09;、期望值#xff08;A#xff0…CAS 原子操作
CASCompare and Swap是一种并发算法通常用于实现多线程环境下的同步操作特别是在并发编程中实现无锁算法。CAS操作涉及三个参数内存位置V、期望值A和新值B。操作的意义是仅当V的值等于A时才将V的值更新为B。整个操作是原子的不会被其他线程中断。
下面是CAS的基本原理
读取内存值V 线程首先读取共享变量的当前值V。比较并交换Compare and Swap 线程比较读取的值V与预期的值A。如果相等说明在读取值的过程中没有其他线程对该变量进行修改那么线程将新值B写入内存位置否则说明有其他线程对该变量进行了修改CAS操作失败线程需要重新尝试。原子性保证 整个比较并交换的过程是原子性的即在整个操作过程中不会被其他线程中断。 CAS优点 避免了使用锁带来的性能开销因为它不会使线程阻塞而是采用乐观的方式尝试更新共享变量 CAS缺点 ABA问题 如果一个变量原来的值是A线程1将其改为B然后又改回A此时线程2通过CAS检查发现值仍然是A认为没有被修改但实际上已经发生了变化。为了解决ABA问题可以使用版本号等方式引入更多信息。循环时间长开销大 在CAS操作失败时线程需要不断地重试直到成功为止。这可能导致一些线程长时间无法完成操作增加了开销。只能保证一个共享变量的原子操作 CAS只能对单一的共享变量进行原子操作无法支持类似于整个事务的复合操作。 CAS 示例
public class CASExample {public static void main(String[] args) {// 创建一个AtomicInteger初始值为0AtomicInteger atomicInteger new AtomicInteger(0);// 执行CAS操作尝试将值从0更新为1boolean casResult atomicInteger.compareAndSet(0, 1);if (casResult) {System.out.println(CAS success. new value: atomicInteger.get());} else {System.out.println(CAS failed.);}// 尝试再次执行CAS操作将值从0更新为2但由于当前值已经是1操作会失败casResult atomicInteger.compareAndSet(0, 2);if (casResult) {System.out.println(CAS successful. new value: atomicInteger.get());} else {System.out.println(CAS failed.);}}
}Connected to the target VM, address: 127.0.0.1:64335, transport: socket
CAS success. new value: 1
CAS failed.UnSafe 原子操作
Unsafe 类是 Java 中的一个非常特殊且强大的类它提供了直接访问内存和执行 CASCompare and Swap等底层操作的方法。然而Unsafe 类并不是官方公开的 API并且在 Java 9 中进行了限制不再推荐使用。因此如果可能最好避免直接使用 Unsafe 类。
以下是一些 Unsafe 类的主要功能
内存操作 Unsafe 类提供了一些方法可以直接操作内存如allocateMemory、freeMemory、putXXX 和 getXXX 等方法其中 XXX 表示不同的数据类型。对象操作 Unsafe 类允许直接操作对象的内部字段比如获取和设置字段的值甚至可以直接修改对象的类。这些操作可能绕过了 Java 的访问权限检查。CAS 操作 Unsafe 类提供了 CAS 相关的方法例如 compareAndSwapInt、compareAndSwapLong、compareAndSwapObject 等用于实现无锁算法。数组操作 Unsafe 提供了一系列用于操作数组元素的方法例如 putIntVolatile、getIntVolatile 等。类加载 Unsafe 类还提供了一些用于加载类和定义类的方法。
AtomicInteger
AtomicInteger 是一种用于执行原子操作的整型类。它常用于在多线程环境下对计数器进行操作。
int get() // 获取当前 AtomicInteger 对象的当前值。
void set(int newValue) // 设置 AtomicInteger 对象的值为指定的新值。
int getAndIncrement() // 原子性地将当前值加 1并返回加 1 前的值
int incrementAndGet() // 原子性地将当前值加 1并返回加 1 后的值。
boolean compareAndSet(int expect, int update) // 如果当前值等于预期值 expect则将当前值更新为新值 update返回更新是否成功的结果。
int addAndGet(int delta)// 原子性地将当前值与给定的增量 delta 相加并返回相加后的值。
void lazySet(int newValue) //使用lazySet设置值后其他线程可能会在之后的一小段时间内读到的还是旧值更新为newValue有延迟。AtomicInteger使用示例
import java.util.concurrent.atomic.AtomicInteger;public class AtomicIntegerExample {public static void main(String[] args) {AtomicInteger counter new AtomicInteger(0);// 原子性地增加计数器值int incrementedValue counter.incrementAndGet();System.out.println(Incremented Value: incrementedValue);}
}AtomicBoolean
AtomicBoolean 提供对布尔类型变量的原子操作通常用于在多线程环境下实现一些状态标记。
// 获取当前 AtomicBoolean 对象的当前值。
boolean get()
// 设置 AtomicBoolean 对象的值为指定的新值。
void set(boolean newValue)
// 原子性地设置 AtomicBoolean 对象的新值并返回设置前的旧值。
boolean getAndSet(boolean newValue)
// 如果当前值等于预期值 expect则将当前值更新为新值 update返回更新是否成功的结果。
boolean compareAndSet(boolean expect, boolean update)
// 与 compareAndSet 方法类似但不一定提供强制的内存同步。
boolean weakCompareAndSet(boolean expect, boolean update)AtomicBoolean使用示例
import java.util.concurrent.atomic.AtomicBoolean;public class AtomicBooleanExample {public static void main(String[] args) {AtomicBoolean flag new AtomicBoolean(true);// 原子性地将标志值设置为falseflag.compareAndSet(true, false);System.out.println(Flag Value: flag.get());}
}AtomicReference
AtomicReference 允许原子性地操作引用类型变量。下面是一个示例演示如何原子性地更新引用值
AtomicReference(V initialValue) // 构造函数创建一个AtomicReference实例初始值为initialValue。
V get() // 获取当前引用的值。
void set(V newValue) // 设置当前引用的值为newValue。
boolean compareAndSet(V expect, V update) // 如果当前引用的值等于expect则将当前引用的值设置为update返回true否则返回false。
V getAndSet(V newValue) // 设置当前引用的值为newValue并返回先前的值。
boolean weakCompareAndSet(V expect, V update) // 类似于compareAndSet但是对于某些实现不保证对 expect 和 update 的原子性检查。
String toString() // 返回当前引用的字符串表示形式。AtomicReference使用示例
import java.util.concurrent.atomic.AtomicReference;public class AtomicReferenceExample {public static void main(String[] args) {AtomicReferenceString reference new AtomicReference(initialValue);// 如果当前值为initialValue则设置为newValuereference.compareAndSet(initialValue, newValue);System.out.println(Reference Value: reference.get());}
}AtomicStampedReference
AtomicStampedReference 在 AtomicReference 的基础上增加了版本号用于解决ABA问题。
// 构造方法
AtomicStampedReference(V initialRef, int initialStamp)
// 返回当前引用
V getReference()
// 返回当前标记
int getStamp()
// 返回当前引用并将当前标记存储在 stampHolder[0] 中
V get(int[] stampHolder)
// 如果当前引用和标记与 expectedReference、expectedStamp 相等则使用 newReference 和 newStamp 更新引用和标记。该方法在CAS操作的基础上进行判断避免了ABA问题。
boolean compareAndSet(V expectedReference, V newReference, int expectedStamp, int newStamp)
// 与 compareAndSet 方法相同但被声明为 weak通常在不需要保证线程间同步的场景使用。
boolean weakCompareAndSet(V expectedReference, V newReference, int expectedStamp, int newStamp)AtomicStampedReference使用示例
import java.util.concurrent.atomic.AtomicStampedReference;public class AtomicStampedReferenceExample {public static void main(String[] args) {AtomicStampedReferenceString stampedReference new AtomicStampedReference(initialValue, 0);// 如果当前值为initialValue且版本号为0则设置为newValue和版本号1stampedReference.compareAndSet(initialValue, newValue, 0, 1);System.out.println(Stamped Reference Value: stampedReference.getReference());System.out.println(Stamped Reference Stamp: stampedReference.getStamp());}
}